Table of contents
- Figure 1: Cobalt corrosion data for wild type cells, ∆phz mutants,
spent medium, and abiotic controls in sterile medium
(done)
- Figure S1: ANOVA test on cobalt concentrations sampled at 168 hours
in biotic vs abiotic treatments with and without mass balance correction
(done)
- Figure S2: ANOVA test on abiotic controls with and without
phenazine-1-carboxylic acid (done)
- Figure 2: Phenazine metabolite concentrations measured via LC-HRMS
(done)
- Figure 3: Wild type vs ∆phz mutant cell growth in corrosion assays
(done)
- Figure S5: Cobalt concentrations for wild type cells that were
acidified then filtered, or filtered then acidified (done)
- Figure S6. Dose response curves for wild type cell growth rate as a
function of cobalt concentration (done)
- Figure S14: ANOVA test on live cells with and without DMSO
- Bioinformatics analyses of genome annotations generated with
DRAM
Packages required
Load all of these packages before running any of the chunks of code
in the subsections below.
library(tidyverse)
library(readxl)
library(data.table)
library(plotly)
library(Cairo)
library(lmtest)
library(car)
library(wesanderson)
library(ggbreak)
library(scales)
library(ggh4x)
library(ggtext)
library(drc)
Figure 1: Cobalt corrosion data for wild type cells, ∆phz mutants,
spent medium, and abiotic controls in sterile medium
- Use the code below to load in source data.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
- Use the code below to generate the scatterplot containing the
categories of interest.
#Adjust the presentation aesthetics
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "grey20",
size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
axis.text.y = element_text(color = "grey20",
size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),
axis.title.x = element_text(color = "grey20",
size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
axis.title.y = element_text(color = "grey20",
size = 34, angle = 90, face = "bold"),
strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
strip.text.y = element_text(size = 32, colour = "grey20"),
plot.title = element_text(size = 30, face = "bold", hjust = .5),
legend.title=element_text(size=32, face = "bold"),
legend.text=element_text(size=32),
panel.border = element_rect(colour = "black", fill=NA, size=1))
#Create custom display orders
All_cobalt_data_combined$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined$Abiotic_vs_biotic,
levels = c("Wild type",
"∆phz",
"Spent medium",
"Sterile medium"))
All_cobalt_data_combined$Metabolite_treatment_ordered <- factor(All_cobalt_data_combined$Metabolite_treatment,
levels = c("Nothing added",
"PCA",
"MeOH"))
#Graphing script with additional data manipulation
library(wesanderson)
Abiotic_vs_biotic_treatment_scatterplot <- All_cobalt_data_combined %>%
filter(DMSO_treatment == "No DMSO") %>% #use this to only focus on experiments that did not receive DMSO
filter(Sample_preservation == "Acidified, filtered") %>% #216 observations
group_by(Abiotic_vs_biotic, Wire_treatment, DMSO_treatment, Metabolite_treatment, Time) %>%
mutate(
Mean_cobalt_concentration_ug_L = mean(Cobalt_concentration_ug_L),
Median_cobalt_concentration_ug_L = median(Cobalt_concentration_ug_L),
Stdev_cobalt_concentration_ug_L = sd(Cobalt_concentration_ug_L),
Min_cobalt_concentration_ug_L = min(Cobalt_concentration_ug_L),
Max_cobalt_concentration_ug_L = max(Cobalt_concentration_ug_L),
Mean_cobalt_concentration_uM = mean(Cobalt_concentration_uM),
Median_cobalt_concentration_uM = median(Cobalt_concentration_uM),
Stdev_cobalt_concentration_uM = sd(Cobalt_concentration_uM),
Min_cobalt_concentration_uM = min(Cobalt_concentration_uM),
Max_cobalt_concentration_uM = max(Cobalt_concentration_uM)) %>%
relocate(Mean_cobalt_concentration_ug_L:Max_cobalt_concentration_uM, .after = Cobalt_concentration_uM) %>%
filter(!Bottle_number == "1") %>% #remove outlier sterile control
#plotting script
ggplot(aes(x=Time,
y = Mean_cobalt_concentration_uM,
colour = Abiotic_vs_biotic_ordered,
shape = Metabolite_treatment_ordered)) +
geom_point(size = 6) +
geom_errorbar(aes(ymin = Mean_cobalt_concentration_uM - Stdev_cobalt_concentration_uM,
ymax = Mean_cobalt_concentration_uM + Stdev_cobalt_concentration_uM)) +
geom_line(aes(group = Bottle_number, color = Abiotic_vs_biotic_ordered))+
scale_x_continuous(breaks = seq(0, 168, by = 24)) +
facet_grid(~ Wire_treatment) +
ylab("Cobalt\nconcentration (µM)") +
xlab("Time elapsed (hours)") +
scale_color_manual(name = "Abiotic vs biotic",
values = wes_palette("Darjeeling1", n = 4),
labels = c("Wild type",
expression(italic("∆phz")),
"Spent medium",
"Sterile medium"))+
scale_shape_discrete(name = "Metabolite treatment") +
theme +
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2))
#Add a layer to angle the text
Abiotic_vs_biotic_treatment_scatterplot_angled <- Abiotic_vs_biotic_treatment_scatterplot + theme(axis.text.x = element_text(angle = 45))
#Save in different image formats at 300 dpi
ggsave("Fig1_Cobalt_ICPMS_data_abiotic_biotic_and_metabolite_treatments_no_DMSO_scatterplot_angled.jpg", dpi = 300, height=8, width=22, device= jpeg)
ggsave("Fig1_Cobalt_ICPMS_data_abiotic_biotic_and_metabolite_treatments_no_DMSO_scatterplot_angled.tiff", dpi = 300, height=8, width=22, device= tiff)
ggsave("Fig1_Cobalt_ICPMS_data_abiotic_biotic_and_metabolite_treatments_no_DMSO_scatterplot_angled.pdf", dpi = 300, height=8, width=22, device= cairo_pdf)
Figure S1: ANOVA test on cobalt concentrations sampled at 168 hours
in biotic vs abiotic treatments with and without mass balance
correction
Figure S1A: ANOVA test without recoveries applied
- Load the cobalt data and trim it where the wire was supplied.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
Abiotic_vs_biotic_wire_only_ANOVA_data <- All_cobalt_data_combined %>%
filter(DMSO_treatment == "No DMSO") %>%
filter(Sample_preservation == "Acidified, filtered") %>%
filter(Time == 168) %>%
filter(Metabolite_treatment == "Nothing added") %>%
filter(Wire_treatment == "Wire included") #24 observations
- Generate the ANOVA model with type III sum of squares to account for
the unbalanced design and interpret visualizations for linear model
assumptions
Abiotic_vs_biotic_model <- lm(Cobalt_concentration_uM ~ Abiotic_vs_biotic, data = Abiotic_vs_biotic_wire_only_ANOVA_data,
contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model
Call:
lm(formula = Cobalt_concentration_uM ~ Abiotic_vs_biotic, data = Abiotic_vs_biotic_wire_only_ANOVA_data,
contrasts = list(Abiotic_vs_biotic = contr.sum), type = 3)
Coefficients:
(Intercept) Abiotic_vs_biotic1 Abiotic_vs_biotic2 Abiotic_vs_biotic3
1392.9 1296.3 -832.6 -1095.6
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model)

#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model)
studentized Breusch-Pagan test
data: Abiotic_vs_biotic_model
BP = 8.3264, df = 3, p-value = 0.03973
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model$residuals)
Shapiro-Wilk normality test
data: Abiotic_vs_biotic_model$residuals
W = 0.95531, p-value = 0.3516
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model)
Durbin-Watson test
data: Abiotic_vs_biotic_model
DW = 1.9404, p-value = 0.3295
alternative hypothesis: true autocorrelation is greater than 0
Interpretation
- Homoscedasticity looks like it may be a slight issue especially as
cobalt concentrations get higher.
- There are a few slightly problematic values on the Q-Q residuals
plot that may need to be addressed with a log transform (value 6 in
particular).
- BP test returns a p-value of 0.03973, so we reject the null
hypothesis of homoscedasticity (as expected).
- SW test returns a p-value of 0.3516, so we cannot reject
the null hypothesis that residuals are normally distributed.
- DW test returns a p-value of 0.3295, so we cannot reject
the null hypothesis that there is no autocorrelation between data
points.
- Re-run the model with a log10 transform to address the issues
associated with homoscedasticity.
Abiotic_vs_biotic_model_log10 <- lm(log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic, data = Abiotic_vs_biotic_wire_only_ANOVA_data,
contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model_log10
Call:
lm(formula = log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic,
data = Abiotic_vs_biotic_wire_only_ANOVA_data, contrasts = list(Abiotic_vs_biotic = contr.sum),
type = 3)
Coefficients:
(Intercept) Abiotic_vs_biotic1 Abiotic_vs_biotic2 Abiotic_vs_biotic3
2.9668 0.4585 -0.2265 -0.5551
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model_log10)

#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model_log10)
studentized Breusch-Pagan test
data: Abiotic_vs_biotic_model_log10
BP = 2.8111, df = 3, p-value = 0.4217
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model_log10$residuals)
Shapiro-Wilk normality test
data: Abiotic_vs_biotic_model_log10$residuals
W = 0.91582, p-value = 0.04725
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model_log10)
Durbin-Watson test
data: Abiotic_vs_biotic_model_log10
DW = 1.5357, p-value = 0.0736
alternative hypothesis: true autocorrelation is greater than 0
Interpretation
- Homoscedasticity looks like it wikll be less of an issue, although
now value point 1, the outlier, is problematic.
- BP test returns a p-value of 0.4217, so we cannot reject
the null hypothesis of homoscedasticity.
- SW test returns a p-value of 0.04725, so we reject the null
hypothesis that residuals are normally distributed.
- DW test returns a p-value of 0.0736, so we cannot reject
the null hypothesis that there is no autocorrelation between data
points.
The issue with the potential outlier is back. This was a contaminated
sterile control, so there is a biological reason to remove it
from consideration.
- Re-run the model removing the outlier and then log10-transforming
the data to address issues of normal distribution of residuals.
Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed <- All_cobalt_data_combined %>%
filter(DMSO_treatment == "No DMSO") %>%
filter(Sample_preservation == "Acidified, filtered") %>%
filter(Time == 168) %>%
filter(Metabolite_treatment == "Nothing added") %>%
filter(Wire_treatment == "Wire included") %>%
filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") #suspected outlier
##Generate model
Abiotic_vs_biotic_model_log10_outlier_removed <- lm(log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic,
data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed ,
contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model_log10_outlier_removed
Call:
lm(formula = log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic,
data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed,
contrasts = list(Abiotic_vs_biotic = contr.sum), type = 3)
Coefficients:
(Intercept) Abiotic_vs_biotic1 Abiotic_vs_biotic2 Abiotic_vs_biotic3
2.9527 0.4727 -0.2124 -0.5975
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model_log10_outlier_removed)

#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model_log10_outlier_removed)
studentized Breusch-Pagan test
data: Abiotic_vs_biotic_model_log10_outlier_removed
BP = 2.7282, df = 3, p-value = 0.4355
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model_log10_outlier_removed$residuals)
Shapiro-Wilk normality test
data: Abiotic_vs_biotic_model_log10_outlier_removed$residuals
W = 0.97364, p-value = 0.7751
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model_log10_outlier_removed)
Durbin-Watson test
data: Abiotic_vs_biotic_model_log10_outlier_removed
DW = 1.9467, p-value = 0.3395
alternative hypothesis: true autocorrelation is greater than 0
Interpretation
- Homoscedasticity looks okay as does the normal distribution of
residuals.
- BP test returns a p-value of 0.4355, so we cannot reject the null
hypothesis of homoscedasticity.
- SW test returns a p-value of 0.7751, so we cannot reject the null
hypothesis that residuals are normally distributed.
- DW test returns a p-value of 0.3395, so we cannot reject the null
hypothesis that there is no autocorrelation between data points.
All linear model assumptions are met
- Generate the output of anova model generated with the data where the
outlier removed and a log10 transformation was applied. This is
returning a type 2 sum of squares because we are no longer considering
the interaction having controlled for wire treatment
Abiotic_vs_biotic_type_II_ANOVA_results <- Anova(Abiotic_vs_biotic_model_log10_outlier_removed, type = 3)
Abiotic_vs_biotic_type_II_ANOVA_results
Anova Table (Type III tests)
Response: log10(Cobalt_concentration_uM)
Sum Sq Df F value Pr(>F)
(Intercept) 179.347 1 11055.428 < 2.2e-16 ***
Abiotic_vs_biotic 4.736 3 97.323 1.03e-11 ***
Residuals 0.308 19
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretation
- There are significant differences in cobalt concentration at 168
hours that are attributable to the different abiotic vs biotic
treatments.
- Run a Tukey post-hoc test to identify where the significant
differences occur between treatments
#First you need to convert the model to an aov object
Abiotic_vs_biotic_model_log10_outlier_removed_converted <- aov(Abiotic_vs_biotic_model_log10_outlier_removed)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed <- TukeyHSD(Abiotic_vs_biotic_model_log10_outlier_removed_converted, conf.level = 0.95)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = Abiotic_vs_biotic_model_log10_outlier_removed)
$Abiotic_vs_biotic
diff lwr upr p adj
Spent medium-∆phz -0.6850227 -0.9382649 -0.43178053 0.0000020
Sterile medium-∆phz -1.0701513 -1.2853658 -0.85493679 0.0000000
Wild type-∆phz -0.1354851 -0.3666625 0.09569234 0.3771351
Sterile medium-Spent medium -0.3851286 -0.6003430 -0.16991407 0.0003969
Wild type-Spent medium 0.5495376 0.3183602 0.78071506 0.0000120
Wild type-Sterile medium 0.9346662 0.7459106 1.12342176 0.0000000
Tukey_comparison_abiotic_vs_biotic_data_frame <- as.data.frame(Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed$Abiotic_vs_biotic)
write.table(Tukey_comparison_abiotic_vs_biotic_data_frame,
file = "Tukey_comparison_results_abiotic_vs_biotic_log10_outlier_removed_20250401.txt", sep = "\t",
row.names = FALSE, col.names = TRUE)
Interpretation
- There are significant differences between:
- Spent medium vs ∆phz
- Sterile medium vs ∆phz
- Sterile medium vs spent medium
- Wild type vs spent medium
- Wild type vs sterile medium
- The only non-significant difference is between wild type and
∆phz
- Letters to add to plots:
- Wild type: A
- ∆phz: A
- Spent medium: B
- Sterile medium: C
- Generate boxplots that will be used to overlay the Tukey annotations
manually in an image editor
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),
axis.text.y = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),
axis.title.x = element_text(color = "grey20", size = 18, angle = 0, hjust = 0.5, vjust = -1, face = "plain"),
axis.title.y = element_text(color = "grey20", size = 18, angle = 90, face = "plain"),
strip.text.x = element_text(size = 20, colour = "grey20"),
strip.text.y = element_text(size = 20, colour = "grey20"),
plot.title = element_text(size = 18, face = "bold", hjust = 0.5, vjust = 1),
legend.title=element_text(size=18),
legend.text=element_text(size=18),
legend.position = "right",
panel.border = element_rect(colour = "black", fill=NA, size=1))
#Create custom order to display x-axis
All_cobalt_data_combined$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined$Abiotic_vs_biotic,
levels = c("Wild type",
"∆phz",
"Spent medium",
"Sterile medium"))
Abiotic_vs_biotic_wire_only_boxplot_log10 <- All_cobalt_data_combined %>%
filter(DMSO_treatment == "No DMSO") %>%
filter(Sample_preservation == "Acidified, filtered") %>%
filter(Time == 168) %>%
filter(Metabolite_treatment == "Nothing added") %>%
filter(Wire_treatment == "Wire included") %>%
filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") %>% #suspected outlier
#Graphing script
ggplot(aes(x=Abiotic_vs_biotic_ordered, y=log10(Cobalt_concentration_uM))) +
geom_boxplot() +
geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
ylim(0, 3.5)+
labs(title = "" ,
y = "log10(Cobalt concentration (µM))",
x = "Abiotic and biotic treatments") +
theme + #this calls the aesthetic theme variable
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2))
Abiotic_vs_biotic_wire_only_boxplot_log10 #anotate this manually in an image editor
#Save files in different formats
ggsave("FigS1A_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_20250514.jpg", dpi = 300, height=6, width=9, device= jpeg)
ggsave("FigS1A_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_20250514.tiff", dpi = 300, height=6, width=9, device= tiff)
ggsave("FigS1A_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_20250514.pdf", dpi = 300, height=6, width=9, device=cairo_pdf)

Fig S1B: ANOVA test with mass balance recoveries applied
- Load in the data from the manually adjusted tab-delimited file that
contains recoveries. Generate a new variable where the recovery has been
applied.
All_cobalt_data_combined_recoveries <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto") %>%
mutate(Cobalt_concentration_uM_corrected = Cobalt_concentration_uM/Recovery) %>% #apply recoveries
relocate(Cobalt_concentration_uM_corrected, .after = Cobalt_concentration_uM)
- Run the model applying the same outlier removal and
log-transformations used on the data that was not corrected for
recovery.
Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed_recoveries <- All_cobalt_data_combined_recoveries %>%
filter(DMSO_treatment == "No DMSO") %>%
filter(Sample_preservation == "Acidified, filtered") %>%
filter(Time == 168) %>%
filter(Metabolite_treatment == "Nothing added") %>%
filter(Wire_treatment == "Wire included") %>%
filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F")
##Generate model
Abiotic_vs_biotic_model_log10_outlier_removed_recoveries <- lm(log10(Cobalt_concentration_uM_corrected) ~ Abiotic_vs_biotic,
data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed_recoveries,
contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model_log10_outlier_removed_recoveries
Call:
lm(formula = log10(Cobalt_concentration_uM_corrected) ~ Abiotic_vs_biotic,
data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed_recoveries,
contrasts = list(Abiotic_vs_biotic = contr.sum), type = 3)
Coefficients:
(Intercept) Abiotic_vs_biotic1 Abiotic_vs_biotic2 Abiotic_vs_biotic3
2.9402 0.3866 -0.1822 -0.5807
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)

#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)
studentized Breusch-Pagan test
data: Abiotic_vs_biotic_model_log10_outlier_removed_recoveries
BP = 2.7282, df = 3, p-value = 0.4355
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries$residuals)
Shapiro-Wilk normality test
data: Abiotic_vs_biotic_model_log10_outlier_removed_recoveries$residuals
W = 0.97364, p-value = 0.7751
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)
Durbin-Watson test
data: Abiotic_vs_biotic_model_log10_outlier_removed_recoveries
DW = 1.9467, p-value = 0.3395
alternative hypothesis: true autocorrelation is greater than 0
Interpretation
- Homoscedasticity looks okay as does the normal distribution of
residuals.
- BP test returns a p-value of 0.4355, so we cannot reject the null
hypothesis of homoscedasticity.
- SW test returns a p-value of 0.7751, so we cannot reject the null
hypothesis that residuals are normally distributed.
- DW test returns a p-value of 0.3395, so we cannot reject the null
hypothesis that there is no autocorrelation between data points.
All linear model assumptions are met
- Generate the actual output of anova model generated with the data
where the outlier removed and a log10 transformation was applied. This
is returning a type 2 sum of squares because we are not longer
considering the interaction having controlled for wire treatment
Abiotic_vs_biotic_type_II_ANOVA_results_recoveries <- Anova(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries, type = 3)
Abiotic_vs_biotic_type_II_ANOVA_results_recoveries
Anova Table (Type III tests)
Response: log10(Cobalt_concentration_uM_corrected)
Sum Sq Df F value Pr(>F)
(Intercept) 177.840 1 10962.516 < 2.2e-16 ***
Abiotic_vs_biotic 4.414 3 90.699 1.925e-11 ***
Residuals 0.308 19
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretation
- There are significant differences in cobalt concentration at 168
hours that are attributable to the different abiotic vs biotic
treatments even after correcting for recoveries.
- The p-values are different for the recovery corrected data, but both
version of the data have p < 0.001.
- Run a Tukey post-hoc test to figure out where the significant
differences are.
library(data.table)
#First you need to convert the model to an aov object
Abiotic_vs_biotic_model_log10_outlier_removed_converted_recoveries <- aov(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed_recoveries <- TukeyHSD(Abiotic_vs_biotic_model_log10_outlier_removed_converted_recoveries, conf.level = 0.95)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed_recoveries
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)
$Abiotic_vs_biotic
diff lwr upr p adj
Spent medium-∆phz -0.56877805 -0.8220202 -0.3155359 0.0000256
Sterile medium-∆phz -0.96735967 -1.1825741 -0.7521452 0.0000000
Wild type-∆phz -0.01037323 -0.2415507 0.2208042 0.9992557
Sterile medium-Spent medium -0.39858162 -0.6137961 -0.1833671 0.0002701
Wild type-Spent medium 0.55840482 0.3272274 0.7895823 0.0000097
Wild type-Sterile medium 0.95698644 0.7682309 1.1457420 0.0000000
Tukey_comparison_abiotic_vs_biotic_data_frame_recoveries <- as.data.frame(Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed_recoveries$Abiotic_vs_biotic)
write.table(Tukey_comparison_abiotic_vs_biotic_data_frame_recoveries,
file = "Tukey_comparison_results_abiotic_vs_biotic_log10_outlier_removed_recoveries_20250513.txt", sep = "\t",
row.names = FALSE, col.names = TRUE)
Interpretation
- There are significant differences between:
- Spent medium vs ∆phz
- Sterile medium vs ∆phz
- Sterile medium vs spent medium
- Wild type vs spent medium
- Wild type vs sterile medium
- The only non-significant difference is between wild type and
∆phz
- Expected letters
- Wild type: A
- ∆phz: A
- Spent medium: B
- Sterile medium: C
- Regenerate boxplots that will be used to overlay the Tukey
annotations manually.
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),
axis.text.y = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),
axis.title.x = element_text(color = "grey20", size = 18, angle = 0, hjust = 0.5, vjust = -1, face = "plain"),
axis.title.y = element_text(color = "grey20", size = 18, angle = 90, face = "plain"),
strip.text.x = element_text(size = 20, colour = "grey20"),
strip.text.y = element_text(size = 20, colour = "grey20"),
plot.title = element_text(size = 18, face = "bold", hjust = 0.5, vjust = 1),
legend.title=element_text(size=18),
legend.text=element_text(size=18),
legend.position = "right",
panel.border = element_rect(colour = "black", fill=NA, size=1))
#Create custom order to display x-axis
All_cobalt_data_combined_recoveries$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined_recoveries$Abiotic_vs_biotic,
levels = c("Wild type",
"∆phz",
"Spent medium",
"Sterile medium"))
Abiotic_vs_biotic_wire_only_boxplot_log10_recoveries <- All_cobalt_data_combined_recoveries %>%
filter(DMSO_treatment == "No DMSO") %>%
filter(Sample_preservation == "Acidified, filtered") %>%
filter(Time == 168) %>%
filter(Metabolite_treatment == "Nothing added") %>%
filter(Wire_treatment == "Wire included") %>%
filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") %>% #suspected outlier
#Graphing script
ggplot(aes(x=Abiotic_vs_biotic_ordered, y=log10(Cobalt_concentration_uM_corrected))) +
geom_boxplot() +
geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
ylim(0, 3.5)+
labs(title = "" ,
y = "log10(Cobalt concentration (µM)\ncorrected for recovery)",
x = "Abiotic and biotic treatments") +
theme + #this calls the aesthetic theme variable
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2))
Abiotic_vs_biotic_wire_only_boxplot_log10_recoveries #anotate this manually in an image editor
ggsave("FigS1B_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_recoveries_applied_20250513.jpg", dpi = 300, height=6, width=9, device=jpeg)
ggsave("FigS1B_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_recoveries_applied_20250513..tiff", dpi = 300, height=6, width=9, device=tiff)
ggsave("FigS1B_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_recoveries_applied_20250513.pdf", dpi = 300, height=6, width=9, device=cairo_pdf)

Figure S2: ANOVA test on abiotic controls with and without
phenazine-1-carboxylic acid
- Load the data frame from the compiled data and remove the outlier
value from the sterile medium treatment that was contaminated.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
#Create custom order for x-axis
All_cobalt_data_combined$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined$Abiotic_vs_biotic,
levels = c("Wild type",
"∆phz",
"Spent medium",
"Sterile medium"))
All_cobalt_data_combined$Metabolite_treatment_ordered <- factor(All_cobalt_data_combined$Metabolite_treatment,
levels = c("Nothing added",
"PCA",
"MeOH"))
Abiotic_no_outlier <- All_cobalt_data_combined %>%
filter(DMSO_treatment == "No DMSO") %>% #use this to only focus on experiments that did not receive DMSO
filter(Sample_preservation == "Acidified, filtered") %>% #216 observations
filter(Time == 168 & Wire_treatment == "Wire included") %>% #Only look at no metabolite spikes + 168 hours
filter(Abiotic_vs_biotic_ordered == "Sterile medium") %>%
filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") #remove outlier
- Generate the linear models and verify assumptions for the ANOVA
using type III sum of squares.
##Generate model
Abiotic_model_outlier_removed <- lm(Cobalt_concentration_uM ~ Metabolite_treatment,
data = Abiotic_no_outlier,
contrasts = list(Metabolite_treatment = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
extra argument ‘type’ will be disregardedg
Abiotic_model_outlier_removed
Call:
lm(formula = Cobalt_concentration_uM ~ Metabolite_treatment,
data = Abiotic_no_outlier, contrasts = list(Metabolite_treatment = contr.sum),
type = 3)
Coefficients:
(Intercept) Metabolite_treatment1 Metabolite_treatment2
213.898 8.048 23.949
par(mfrow = c(2,2))
plot(Abiotic_model_outlier_removed)

#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_model_outlier_removed)
studentized Breusch-Pagan test
data: Abiotic_model_outlier_removed
BP = 2.6841, df = 2, p-value = 0.2613
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_model_outlier_removed$residuals)
Shapiro-Wilk normality test
data: Abiotic_model_outlier_removed$residuals
W = 0.93943, p-value = 0.3753
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_model_outlier_removed)
Durbin-Watson test
data: Abiotic_model_outlier_removed
DW = 2.8872, p-value = 0.9188
alternative hypothesis: true autocorrelation is greater than 0
Interpretation
- Homoscedasticity may be an issue, it looks like samples associated
with higher cobalt concentrations ~ 240 µM have higher variance.
- Normal distribution of residuals looks good.
- BP test returns a p-value of 0.2613 –> we cannot reject
the null hypothesis of homoscedasticity.
- SW test returns a p-value of 0.3753 –> we cannot reject
the null hypothesis of normally distributed residuals.
- DW test returns a p-value of 0.9188 –> we cannot reject
the null hypothesis that there is no autocorrelation between data
points.
All assumptions met, okay to proceed with ANOVA
- Run the ANOVA and the Tukey comparison.
Abiotic_type_III_ANOVA_results <- Anova(Abiotic_model_outlier_removed, type = 3)
Abiotic_type_III_ANOVA_results
Anova Table (Type III tests)
Response: Cobalt_concentration_uM
Sum Sq Df F value Pr(>F)
(Intercept) 529421 1 128.8876 8.946e-08 ***
Metabolite_treatment 7051 2 0.8583 0.4483
Residuals 49291 12
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretation
- Metabolite treatment did not emerge as a significant variable, so
there is no significant differences between groups.
- Generate the boxplot. There is no need to annotate the boxes later
because there are no significant differences.
Abiotic_outlier_removed_boxplot <- Abiotic_no_outlier %>%
ggplot(aes(x=Metabolite_treatment_ordered, y=Cobalt_concentration_uM)) +
geom_boxplot() +
geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
ylim(0, 400) +
labs(title = "" ,
y = "Cobalt concentration (µM)",
x = "Metabolic treatments in sterile medium") +
theme +
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2))
Abiotic_outlier_removed_boxplot
ggsave("FigS2_Cobalt_ICPMS_data_abiotic_treatments_no_DMSO_boxplot.jpg", dpi = 300, height=6, width=6, device=jpeg)
ggsave("FigS2_Cobalt_ICPMS_data_abiotic_treatments_no_DMSO_boxplot.tiff", dpi = 300, height=6, width=6, device=tiff)
ggsave("FigS2_Cobalt_ICPMS_data_abiotic_treatments_no_DMSO_boxplot.pdf", dpi = 300, height=6, width=6, device=cairo_pdf)

Figure 2: Phenazine metabolite concentrations measured via
LC-HRMS
- Load the formatted LC-HRMS data.
LC_MS_data_combined_labelled_long <- fread("LC_MS_data_combined_20250419.txt", sep = "\t", header = "auto")
- Plot the stacked bar graphs using variables with a custom
order.
barplot_theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "black", size = 32),
axis.text.y = element_text(color = "black", size = 32),
axis.title.x = element_text(color = "black", size = 34, vjust = -3, face = "bold"),
axis.title.y = element_text(color = "black", size = 34, vjust = 6, face = "bold"),
strip.text.x = element_text(color = "black", size = 32, face = "bold"),
strip.text.y = element_text(color = "black", size = 32, face = "bold"),
legend.title=element_text(size=40, vjust = 2, face = "bold"),
legend.text=element_text(size=34),
legend.key = element_rect(fill = "white", color = NA),
plot.title = element_text(size = 68, face = "bold", hjust = 0.5),
panel.border = element_rect(colour = "black", fill=NA, size=1),
plot.margin = unit(c(2, 2, 2, 2), "cm"))
LC_MS_data_combined_labelled_long$Abiotic_vs_biotic_ordered <- factor(LC_MS_data_combined_labelled_long$Abiotic_vs_biotic,
levels = c("Wild type",
"Spent medium",
"∆phz"))
LC_MS_data_combined_labelled_long$Metabolite_ordered <- factor(LC_MS_data_combined_labelled_long$Metabolite,
levels = c("2-OHPCA",
"PCA",
"2-OHPHZ"))
Phenazine_barplot <- LC_MS_data_combined_labelled_long %>%
group_by(Comment) %>%
mutate(Mean_concentration_ug_mL = mean(Concentration_ug_mL)) %>%
ggplot(aes(x= Time, y = Concentration_ug_mL, fill = Metabolite_ordered)) +
geom_bar(aes(group = Replicate), position="stack", stat="identity") +
facet_nested(Replicate~Wire_treatment + Abiotic_vs_biotic_ordered)+
scale_x_continuous(breaks = seq(0, 168, by = 24)) +
scale_fill_manual(name = "Metabolite",
values = c("2-OHPCA" = "#FA1F1E", # Red
"PCA" = "#EBA602", # Gold
"2-OHPHZ" = "#027AB0" # Blue
))+
#scale_fill_brewer(name = "Metabolite", palette = "YlOrRd")+
ylim(0,15) +
theme(axis.text.x=element_text(angle=0, hjust=0.5),
axis.title.y = element_text(color = "black", size = 24, vjust = 0))+
labs(x = "Time elapsed (hours)" , y = "Concentration (µg/mL)") +
barplot_theme +
theme(legend.key.size = unit(2, 'cm'))
Phenazine_barplot
Phenazine_barplot_angled <- Phenazine_barplot + theme(axis.text.x = element_text(angle = 45, vjust = 0.5))
#Save in different image formats
ggsave("Fig2_phenazine_LCMS_data_stacked_barplot_faceted.jpg", dpi = 300, height=12, width=40, device=jpeg)
ggsave("Fig2_phenazine_LCMS_data_stacked_barplot_faceted.tiff", dpi = 300, height=12, width=40, device=tiff)
ggsave("Fig2_phenazine_LCMS_data_stacked_barplot_faceted.pdf", dpi = 300, height=12, width=40, device=cairo_pdf)

Figure 3: Wild type vs ∆phz mutant cell growth in corrosion
assays
- Load the plate count data.
Plate_counts_combined <- fread("Plate_counts_combined_20250527.txt", sep = "\t", header = "auto")
- Add new variables to the data frame parsing the Comment variable
that contains detailed informtion on the sample
Plate_counts_combined_treatments_added <- Plate_counts_combined %>%
#Add time as a numeric vairable
mutate(Time = case_when(grepl("0hr", Comment) ~ "0",
grepl("24hr", Comment) ~ "24",
grepl("72hr", Comment) ~ "72",
grepl("168hr", Comment) ~ "168")) %>%
mutate(Time = as.numeric(Time)) %>%
#Add wire treatment as a dedicated variable and leave as character
mutate(Wire_treatment = case_when(grepl("_Wire", Comment) ~ "Wire included",
grepl("NoWire", Comment) ~ "No wire")) %>%
#Add strain information
mutate(Strain = case_when(grepl("+10%inoc_", Comment) ~ "Wild type",
grepl("DMSO", Comment) ~ "Wild type",
grepl("0%inoc∆phz", Comment) ~ "∆phz")) %>%
#Add DMSO information
mutate(DMSO_treatment = case_when(!grepl("DMSO", Comment) ~ "No DMSO",
grepl("+DMSO", Comment) ~ "DMSO"))
Plate_counts_combined_summary_statistics <- Plate_counts_combined_treatments_added %>%
group_by(Strain, Wire_treatment, DMSO_treatment, Flask_number, Time) %>%
filter(CFU_mL >0) %>% #remove any values that had 0 counts on the plate for graphing
#Calculate plate counts using technical replicates for each flask at each time point
mutate(Technical_mean_CFU_mL = mean(CFU_mL),
Technical_stdev_CFU_mL = sd(CFU_mL)) %>%
ungroup() %>%
#Calculate plate counts using average of technical replicates for all flasks (biological replicates)
group_by(Strain, Wire_treatment, DMSO_treatment, Time) %>%
mutate(Biological_mean_CFU_mL = mean(Technical_mean_CFU_mL),
Biological_stdev_CFU_mL = sd(Technical_mean_CFU_mL))
write.table(Plate_counts_combined_summary_statistics, file = "Plate_counts_combined_summary_statistics_20250419.txt", sep = "\t",
row.names = FALSE, col.names = TRUE)
- Plot the growth data, summarizing the means and standard deviations
prior to the ggplot command.
#Adjust the presentation aesthetics
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "grey20",
size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
axis.text.y = element_text(color = "grey20",
size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),
axis.title.x = element_text(color = "grey20",
size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
axis.title.y = element_text(color = "grey20",
size = 34, angle = 90, face = "bold"),
strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
strip.text.y = element_text(size = 32, colour = "grey20"),
plot.title = element_text(size = 30, face = "bold", hjust = .5),
legend.title=element_text(size=32, face = "bold"),
legend.text=element_text(size=32),
panel.border = element_rect(colour = "black", fill=NA, size=1))
#Create custom display orders
Plate_counts_combined_treatments_added$Strain_ordered <- factor(Plate_counts_combined_treatments_added$Strain,
levels = c("Wild type",
"∆phz",
"Spent medium",
"Sterile medium"))
Growth_curves_log_scale <- Plate_counts_combined_treatments_added %>%
filter(DMSO_treatment == "No DMSO") %>% #use this to only focus on experiments that did not receive DMSO
group_by(Strain, Wire_treatment, DMSO_treatment, Flask_number, Time) %>%
filter(CFU_mL >0) %>% #remove any values that had 0 counts on the plate for graphing
#Calculate plate counts using technical replicates for each flask at each time point
mutate(Technical_mean_CFU_mL = mean(CFU_mL),
Technical_stdev_CFU_mL = sd(CFU_mL)) %>%
ungroup() %>%
#Calculate plate counts using average of technical replicates for all flasks (biological replicates)
group_by(Strain, Wire_treatment, DMSO_treatment, Time) %>%
mutate(Biological_mean_CFU_mL = mean(Technical_mean_CFU_mL),
Biological_stdev_CFU_mL = sd(Technical_mean_CFU_mL)) %>%
#plotting script
ggplot(aes(x=Time, y = log10(Biological_mean_CFU_mL), colour = Strain_ordered)) +
geom_point(size = 6) +
geom_errorbar(aes(ymin = log10(Biological_mean_CFU_mL - Biological_stdev_CFU_mL),
ymax = log10(Biological_mean_CFU_mL + Biological_stdev_CFU_mL))) +
geom_line(aes(group = Flask_number, color = Strain_ordered))+
scale_x_continuous(breaks = seq(0, 168, by = 24))+
facet_grid(~ Wire_treatment) +
ylab("Log10\n(CFU/mL)") +
scale_y_continuous(labels = label_math(), limits = c(5, 10))+
xlab("Time elapsed (hours)") +
scale_color_manual(name = "Strain",
values = wes_palette("Darjeeling1", n = 4),
labels = c("Wild type",
expression(italic("∆phz"))))+
theme +
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2))
Growth_curves_log_scale
Growth_curves_log_scale_no_legend_angled <- Growth_curves_log_scale + theme(axis.text.x = element_text(angle = 45))
ggsave("Fig3_plate_count_data_WT_phz_mutant_scatterplot_log10.jpg", dpi = 300, height=8, width=20, device=jpeg)
ggsave("Fig3_plate_count_data_WT_phz_mutant_scatterplot_log10.tiff", dpi = 300, height=8, width=20, device=tiff)
ggsave("Fig3_plate_count_data_WT_phz_mutant_scatterplot_log10.pdf", dpi = 300, height=8, width=20, device=cairo_pdf)

Figure S5: Cobalt concentrations for wild type cells that were
acidified then filtered, or filtered then acidified
- Use the code below to load in source data.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
- Use this code to create a similar figure to Figure 1 comparing wild
type and sterile medium treatments that did not receive DMSO and were
subject to different sample preservation methods.
#Adjust the presentation aesthetics
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "grey20",
size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
axis.text.y = element_text(color = "grey20",
size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),
axis.title.x = element_text(color = "grey20",
size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
axis.title.y = element_text(color = "grey20",
size = 34, angle = 90, face = "bold"),
strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
strip.text.y = element_text(size = 32, colour = "grey20"),
plot.title = element_text(size = 30, face = "bold", hjust = .5),
legend.title=element_text(size=32, face = "bold"),
legend.text=element_text(size=32),
panel.border = element_rect(colour = "black", fill=NA, size=1))
#Graphing script with additional data manipulation
Acidify_filter_scatterplot <- All_cobalt_data_combined %>%
filter(Wire_treatment == "Wire included") %>% #use this to only focus on experiments that did not receive DMSO
filter(Abiotic_vs_biotic == "Wild type" | Abiotic_vs_biotic == "Sterile medium") %>%
filter(Metabolite_treatment == "Nothing added") %>%
filter(DMSO_treatment == "No DMSO") %>% #96 observations
group_by(Abiotic_vs_biotic, Wire_treatment, DMSO_treatment, Metabolite_treatment, Time, Sample_preservation) %>%
mutate(
Mean_cobalt_concentration_ug_L = mean(Cobalt_concentration_ug_L),
Median_cobalt_concentration_ug_L = median(Cobalt_concentration_ug_L),
Stdev_cobalt_concentration_ug_L = sd(Cobalt_concentration_ug_L),
Min_cobalt_concentration_ug_L = min(Cobalt_concentration_ug_L),
Max_cobalt_concentration_ug_L = max(Cobalt_concentration_ug_L),
Mean_cobalt_concentration_uM = mean(Cobalt_concentration_uM),
Median_cobalt_concentration_uM = median(Cobalt_concentration_uM),
Stdev_cobalt_concentration_uM = sd(Cobalt_concentration_uM),
Min_cobalt_concentration_uM = min(Cobalt_concentration_uM),
Max_cobalt_concentration_uM = max(Cobalt_concentration_uM)) %>%
relocate(Mean_cobalt_concentration_ug_L:Max_cobalt_concentration_uM,
.after = Cobalt_concentration_uM) %>%
filter(!Bottle_number == "1") %>% #remove outlier sterile control
#plotting script
ggplot(aes(x=Time,
y = Mean_cobalt_concentration_uM,
colour = Abiotic_vs_biotic,
)) +
geom_point(size = 6) +
geom_errorbar(aes(ymin = Mean_cobalt_concentration_uM - Stdev_cobalt_concentration_uM,
ymax = Mean_cobalt_concentration_uM + Stdev_cobalt_concentration_uM)) +
geom_line(aes(group = Bottle_number, color = Abiotic_vs_biotic))+
scale_x_continuous(breaks = seq(0, 168, by = 24)) +
facet_grid(~ Sample_preservation) +
ylab("Cobalt concentration (µM)") +
xlab("Time elapsed (hours)") +
scale_color_manual(name = "Abiotic vs biotic",
values = wes_palette("Cavalcanti1", n = 2))+
#scale_shape_discrete(name = "Abiotic vs biotic") +
theme +
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2),
axis.text.x = element_text(angle = 45))
Acidify_filter_scatterplot
#Save the images in different formats
ggsave("FigS5_cobalt_ICPMS_data_sample_preservation_scatterplot.jpg", dpi = 300, height=8, width=20, device=jpeg)
ggsave("FigS5_cobalt_ICPMS_data_sample_preservation_scatterplot.tiff", dpi = 300, height=8, width=20, device=tiff)
ggsave("FigS5_cobalt_ICPMS_data_sample_preservation_scatterplot.pdf", dpi = 300, height=8, width=20, device=cairo_pdf)

Figure S6. Dose response curves for wild type cell growth rate as a
function of cobalt concentration
- Load the summaries generated with the ‘growthcurver’ package that
are the source data for the dose response curve.
P_chlor_aur_growth_summary_variables_added <- fread("Pseudomonas_chlororaphis_aurefociens_growth_curve_summaries.txt", sep = "\t", header = "auto")
- Use the commands in the ‘drc’ package to fit a 5 parameter logistic
regression to create the dose response curve. Use the summary commands
to get quick information on the IC/EC50 values for cobalt
concentration.
P_chlor_aur_growth_rate_5_param_model<- drm(r ~ Cobalt_concentration_uM_numeric,
data = P_chlor_aur_growth_summary_variables_added,
fct = LL.5())
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
summary(P_chlor_aur_growth_rate_5_param_model)
Model fitted: Generalized log-logistic (ED50 as parameter) (5 parms)
Parameter estimates:
Estimate Std. Error t-value p-value
b:(Intercept) 8.360166 19.277199 0.4337 0.6694
c:(Intercept) 0.206760 0.012806 16.1451 1.499e-12 ***
d:(Intercept) 0.461770 0.020284 22.7657 3.048e-15 ***
e:(Intercept) 26.583930 69.763176 0.3811 0.7074
f:(Intercept) 2.008672 34.513367 0.0582 0.9542
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error:
0.04959386 (19 degrees of freedom)
P_chlor_aur_growth_rate_summary_dose_data <- ED(P_chlor_aur_growth_rate_5_param_model, c(5, 10, 50), interval = "delta")
Estimated effective doses
Estimate Std. Error Lower Upper
e:1:5 17.1694 14.5636 -13.3126 47.6514
e:1:10 18.7436 12.7079 -7.8543 45.3415
e:1:50 23.9093 3.7162 16.1313 31.6874
- Plot the dose response curve using base R (most compatible with the
drc package).
P_chlor_aur_growth_rate_dose_response<- plot(P_chlor_aur_growth_rate_5_param_model, broken = FALSE, type = "all",
xlab = "Co(2+) concentration (µM)", xlim = c(0, 1000),
ylab = "Growth rate (hr-1)",
main = "Pseudomonas chlororaphis aureofaciens growth curve in response to Co(2+)")
view(P_chlor_aur_growth_rate_dose_response)
ggsave("FigS6_Pseudomonas_chlororaphis_aureofaciens_growth_rate_cobalt_dose_response_curve.jpg", height=8, width=14, device=jpeg)
#Save in different formats
pdf(file = 'FigS6_Pseudomonas_chlororaphis_aureofaciens_growth_rate_cobalt_dose_response_curve.pdf')
plot(P_chlor_aur_growth_rate_5_param_model, broken = FALSE, type = "all",
xlab = "Co(2+) concentration (µM)", xlim = c(0, 1000),
ylab = "Growth rate (hr-1)",
main = "Pseudomonas chlororaphis aureofaciens \ngrowth curve in response to Co(2+)")
dev.off()
quartz_off_screen
2

#Figure S14: ANOVA test on live cells with and without DMSO
- Load the source data and trim it to the desired samples to carry out
the comparison for the effect of DMSO.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
#Subet DMSO data
DMSO_comparison_data <- All_cobalt_data_combined %>%
filter(Wire_treatment == "Wire included") %>%
filter(Sample_preservation == "Acidified, filtered") %>%
filter(Time == 168) %>%
filter(Abiotic_vs_biotic == "Wild type")
- Use the subset data to generate a linear model that for an ANOVA
comparison. Use this code to verify the assumptions of linear model
fit.
DMSO_comparison_model <- lm(Cobalt_concentration_uM ~ DMSO_treatment, data = DMSO_comparison_data,
contrasts = list(DMSO_treatment = contr.sum), type =3) #need to do this for unabalance sample size
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
extra argument ‘type’ will be disregardedg
DMSO_comparison_model
Call:
lm(formula = Cobalt_concentration_uM ~ DMSO_treatment, data = DMSO_comparison_data,
contrasts = list(DMSO_treatment = contr.sum), type = 3)
Coefficients:
(Intercept) DMSO_treatment1
1205.1 -819.8
par(mfrow = c(2,2))
plot(DMSO_comparison_model)

Interpretation
- Looks like we may have issues with equal variance in the absence of
DMSO.
- Normality looks pretty good excpet for the 5th and 7th data
points.
- Run formal tests to verify the assumptions of linear models.
#Run Breusch Pagan test for homoscedasticity
bptest(DMSO_comparison_model)
studentized Breusch-Pagan test
data: DMSO_comparison_model
BP = 2.9558, df = 1, p-value = 0.08557
#Run Shapir-Wilk normality test
shapiro.test(DMSO_comparison_model$residuals)
Shapiro-Wilk normality test
data: DMSO_comparison_model$residuals
W = 0.95749, p-value = 0.7569
#Run Durbin-Watson test for autocorrelation
dwtest(DMSO_comparison_model)
Durbin-Watson test
data: DMSO_comparison_model
DW = 1.4938, p-value = 0.2141
alternative hypothesis: true autocorrelation is greater than 0
Interpretation
studentized Breusch-Pagan test
data: DMSO_comparison_model BP = 6.5497, df = 3, p-value = 0.08557
p > 0.05 meaning we cannot reject the null hypothesis of
homoscedasticity, this is good (just barely)
Shapiro-Wilk normality test
data: DMSO_comparison_model$residuals W = 0.72204, p-value = 0.7569
p >0.05, meaning we cannot reject the null hypothesis that
are normally distributed.
Durbin-Watson test
data: DMSO_comparison_model DW = 1.9783, p-value = 0.2141
Alternative hypothesis: true autocorrelation is greater than 0
value is close to 2, no significant autocorrelation, p >
0.05 so we can’t reject null hypothesis of no autocorrelation
- Run the ANOVA and the Tukey comparison.
DMSO_type_III_ANOVA_results <- Anova(DMSO_comparison_model, type = 3)
DMSO_type_III_ANOVA_results
Anova Table (Type III tests)
Response: Cobalt_concentration_uM
Sum Sq Df F value Pr(>F)
(Intercept) 13940825 1 65.687 3.976e-05 ***
DMSO_treatment 6451314 1 30.398 0.0005648 ***
Residuals 1697852 8
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interpretation
- DMSO treatment had a significant effect on cobalt concentration at
168 hours for wild type cell experiments.
- Create a boxplot to illustrate this result. There is no need to
annotate because there are only two boxes and the independent variable
was significant.
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black"),
axis.text.x = element_text(color = "grey20",
size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
axis.text.y = element_text(color = "grey20",
size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),
axis.title.x = element_text(color = "grey20",
size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
axis.title.y = element_text(color = "grey20",
size = 34, angle = 90, face = "bold"),
strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
strip.text.y = element_text(size = 32, colour = "grey20"),
plot.title = element_text(size = 30, face = "bold", hjust = .5),
legend.title=element_text(size=32, face = "bold"),
legend.text=element_text(size=32),
panel.border = element_rect(colour = "black", fill=NA, size=1))
DMSO_boxplot <- DMSO_comparison_data %>%
ggplot(aes(x=DMSO_treatment, y=Cobalt_concentration_uM)) +
geom_boxplot() +
geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
ylim(0, 3000) +
labs(title = "" ,
y = "Cobalt\nconcentration (µM)",
x = "DMSO treatment") +
theme +
theme(plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.x = element_text(vjust = -2),
axis.title.y = element_text(vjust = 2),
axis.text.x = element_text(angle = 0))
DMSO_boxplot
#Save different image formats
ggsave("FigS14_cobalt_ICPMS_data_DMSO.jpg", dpi = 300, height=8, width=10, device=jpeg)
ggsave("FigS14_cobalt_ICPMS_data_DMSO.tiff", dpi = 300, height=8, width=10, device=tiff)
ggsave("FigS14_cobalt_ICPMS_data_DMSO.pdf", dpi = 300, height=8, width=10, device=cairo_pdf)

#Bioinformatics analyses of genome annotations generated using
DRAM
Run DRAM for annotations and distillation
- Activate the conda environment containing DRAM and run the annotate
command. Replace the directory and fasta file with the genome file for
Pseudomonas chlororaphis subspecies aurefoaciens (or any genome or
genoems of your choice)
DRAM.py annotate -i 'Pseudomonas_genome_analyses/*.fasta' --use_uniref -o Pseudomonas_annotation_with_uniref --threads 8
- Once the annotation is complete, use the distillation command. Make
sure to use the same output directory from the annotate step.
DRAM.py distill -i Pseudomonas_annotation_with_uniref/annotations.tsv -o Pseudomonas_genome_summaries --trna_path Pseudomonas_annotation_with_uniref/trnas.tsv --rrna_path Pseudomonas_annotation_with_uniref/rrnas.tsv
Manually search for cobalt genes in the annotation output by
DRAM
- Load in the tab-delimited file containing the annotation data.
Pseudomonas_chlororaphis_aureofaciens_annotations <- fread("Pseudomonas_chlororaphis_aureofaciens_DRAM_annotations.tsv", sep = "\t", header = "auto")
- Manually search the annotation file using different strings of test
for functions relevant to cobalt and microbially-induced corrosion.
corrosion_pathways <- Pseudomonas_chlororaphis_aureofaciens_annotations %>%
#Simple text search for "cobalt"
filter(
(if_any(c(kegg_hit:pfam_hits), ~ grepl("cobalt", .))) |
(if_any(c(kegg_hit:pfam_hits), ~ grepl("cob", .))) |
(if_any(c(kegg_hit:pfam_hits), ~ grepl("cyanide", .)))|
(if_any(c(kegg_hit:pfam_hits), ~ grepl("hcn", .)))|
(if_any(c(kegg_hit:pfam_hits), ~ grepl("cytochrome", .)))|
#(if_any(c(kegg_hit:pfam_hits), ~ grepl("hydrogenase", .)))| this is non-specific and picks up anything with dehydrogenase, comment out
(if_any(c(kegg_hit:pfam_hits), ~ grepl("siderophore", .)))) %>%
dplyr::select(scaffold,
gene_position,
start_position,
end_position,
ko_id,
kegg_hit,
uniref_id,
uniref_hit)
#Write the table to save the source data
write.table(corrosion_pathways, file = "SuppData_Pseudomonas_chlororaphis_aureofaciens_putative_corrosion_pathways.tsv", sep = "\t", row.names = FALSE)
Summary of key antiSMASH biosynthetic gene cluster regions
key biosynthetic genes are denoted by asterisks in markdown
format.
Region 2 (hydrogen cyanide cluster): 2951483 to 2964455
Region2 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 2951483 & end_position <=2964455)
Genes in hydrogen cyanide-cluster: - ctg1_2591: 2956483 -
2956800 –> hydrogen cyanide synthase HcnA [EC:1.4.99.5] (C grade,
KEGG ID = K10814) - ctg1_2592: 2956797 - 2958206 –> hydrogen
cyanide synthase HcnB [EC:1.4.99.5] (B grade, KEGG ID = K10815) -
ctg1_2593: 2958199 - 2959455 –> hydrogen cyanide synthase
HcnC [EC:1.4.99.5] (B grade, KEGG ID = K10816) - ctg1_2594: 2959618 -
2960223 –> glutathione S-transferase [EC:2.5.1.18] (B grade, KEGG ID
= K00799)
Region 6 (NI-siderophore): 3832837 to 3869821
Region6 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 3832837 & end_position <=3869821)
Genes in NI-siderophore cluster:
- ctg1_3372: 3846837 - 3848735 –> staphyloferrin
B synthase [EC:6.3.2.56] (B grade KEGG ID = K23375)
- ctg1_3373: 3848740 - 3849513 –> staphyloferrin B
biosynthesis citrate synthase (B grade, KEGG ID = K23376)
- ctg1_3374: 3849507 - 3851369 –>
2-[(L-alanin-3-ylcarbamoyl)methyl]-3-(2-aminoethylcarbamoyl)-2-hydroxypropanoate
synthase [EC:6.3.2.55] (B grade, KEGG ID = K23374)
- ctg1_3375: 3851394 - 3852812 –> UniRef90_A0A554P7Y5 DHA2 family
efflux MFS transporter permease subunit n=30 Tax=Pseudomonadaceae
TaxID=135621 RepID=A0A554P7Y5_9PSED (B grade, no hit in KEGG)
- ctg1_3376: 3852809 - 3854029 –> diaminopimelate decarboxylase
[EC:4.1.1.20] (B grade, KEGG ID = K01586)
- ctg1_3377: 3854022 - 3855821 –> UniRef90_A0A0C5EL69 AcsD
protein n=70 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A0C5EL69_9PSED (B
grade, no hit in KEGG)
Region 7 (hydrogen cyanide cluster): 3888854 to 3901701
Region7 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 3888854 & end_position <=3901701)
- ctg1_3405: 3890984 - 3892441 –> succinate-semialdehyde
dehydrogenase / glutarate-semialdehyde dehydrogenase [EC:1.2.1.16
1.2.1.79 1.2.1.20] (B grade, KEGG ID = K00135)
- ctg1_3406: 3892700 - 3893857 –> acetylornithine deacetylase
[EC:3.5.1.16] (B grade, KEGG ID = K01438)
- ctg1_3407: 3893854 - 3895008 –> UniRef90_A0AA45XIN0
Sarcosine oxidase subunit beta n=5 Tax=Pseudomonas TaxID=286
RepID=A0AA45XIN0_9PSED (no KEGG hit, B grade, UniRef ID =
A0AA45XIN0_9PSED)
- Catalyzes oxidative demethylation of sarcosine (N-methylglycine) to
yield glycine
- ctg1_3408: 3895005 - 3896411 –> UniRef90_A0A3G7K0E2
Opine oxidase subunit A n=39 Tax=Pseudomonas TaxID=286
RepID=A0A3G7K0E2_9PSED, (no KEGG hit, B grade, Uniref ID =
A0A3G7K0E2_9PSED)
- Cleaves opines into amino acids and pyruvate
- ctg1_3409: 3896393 - 3896701 –> UniRef90_A0A5M7CTD1
(2Fe-2S)-binding protein n=14 Tax=Pseudomonadaceae TaxID=135621
RepID=A0A5M7CTD1_9PSED (C grade, no KEGG hit, UniRef ID =
A0A5M7CTD1_9PSED)
- ctg1_3410: 3896698 - 3898539 –> peptide/nickel transport system
ATP-binding protein (B grade, KEGG ID = K02031)
- ctg1_3411: 3898541 - 3899416 –> UniRef90_A0A0C1ZSU6 DNA-directed
RNA polymerase subunit alpha n=30 Tax=Pseudomonadaceae TaxID=135621
RepID=A0A0C1ZSU6_PSEFL (no KEGG hit, B grade, Uniref ID =
A0A0C1ZSU6_PSEFL)
- ctg1_3412: 3899413 - 3900369 –> peptide/nickel transport system
permease protein (B grade, KEGG ID = K02033)
Region 11 (NRPS): 5189456 to 5242472
Region11 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 5189456 & end_position <=5242472)
NRPS region here is really only one gene: - ctg1_4563:
5209456 - 5222472 –> UniRef90_A0A554PEL7 Non-ribosomal peptide
synthetase n=29 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A554PEL7_9PSED
(B grade, no KEGG hit)
LS0tCnRpdGxlOiAiQ29iYWx0IGNvcnJvc2lvbiBHaXRodWIgY29kZWJvb2siCm91dHB1dDogaHRtbF9ub3RlYm9vawplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCiMgVGFibGUgb2YgY29udGVudHMKCi0gRmlndXJlIDE6IENvYmFsdCBjb3Jyb3Npb24gZGF0YSBmb3Igd2lsZCB0eXBlIGNlbGxzLCDiiIZwaHogbXV0YW50cywgc3BlbnQgbWVkaXVtLCBhbmQgYWJpb3RpYyBjb250cm9scyBpbiBzdGVyaWxlIG1lZGl1bSAoKmRvbmUqKQotIEZpZ3VyZSBTMTogQU5PVkEgdGVzdCBvbiBjb2JhbHQgY29uY2VudHJhdGlvbnMgc2FtcGxlZCBhdCAxNjggaG91cnMgaW4gYmlvdGljIHZzIGFiaW90aWMgdHJlYXRtZW50cyB3aXRoIGFuZCB3aXRob3V0IG1hc3MgYmFsYW5jZSBjb3JyZWN0aW9uICgqZG9uZSopCi0gRmlndXJlIFMyOiBBTk9WQSB0ZXN0IG9uIGFiaW90aWMgY29udHJvbHMgd2l0aCBhbmQgd2l0aG91dCBwaGVuYXppbmUtMS1jYXJib3h5bGljIGFjaWQgKCpkb25lKikKLSBGaWd1cmUgMjogUGhlbmF6aW5lIG1ldGFib2xpdGUgY29uY2VudHJhdGlvbnMgbWVhc3VyZWQgdmlhIExDLUhSTVMgKGRvbmUpCi0gRmlndXJlIDM6IFdpbGQgdHlwZSB2cyDiiIZwaHogbXV0YW50IGNlbGwgZ3Jvd3RoIGluIGNvcnJvc2lvbiBhc3NheXMgKGRvbmUpCi0gRmlndXJlIFM1OiBDb2JhbHQgY29uY2VudHJhdGlvbnMgZm9yIHdpbGQgdHlwZSBjZWxscyB0aGF0IHdlcmUgYWNpZGlmaWVkIHRoZW4gZmlsdGVyZWQsIG9yIGZpbHRlcmVkIHRoZW4gYWNpZGlmaWVkIChkb25lKQotIEZpZ3VyZSBTNi4gRG9zZSByZXNwb25zZSBjdXJ2ZXMgZm9yIHdpbGQgdHlwZSBjZWxsIGdyb3d0aCByYXRlIGFzIGEgZnVuY3Rpb24gb2YgY29iYWx0IGNvbmNlbnRyYXRpb24gKGRvbmUpCi0gRmlndXJlIFMxNDogQU5PVkEgdGVzdCBvbiBsaXZlIGNlbGxzIHdpdGggYW5kIHdpdGhvdXQgRE1TTwotIEJpb2luZm9ybWF0aWNzIGFuYWx5c2VzIG9mIGdlbm9tZSBhbm5vdGF0aW9ucyBnZW5lcmF0ZWQgd2l0aCBEUkFNCgojIFBhY2thZ2VzIHJlcXVpcmVkCgpMb2FkIGFsbCBvZiB0aGVzZSBwYWNrYWdlcyBiZWZvcmUgcnVubmluZyBhbnkgb2YgdGhlIGNodW5rcyBvZiBjb2RlIGluIHRoZSBzdWJzZWN0aW9ucyBiZWxvdy4KYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShDYWlybykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KHdlc2FuZGVyc29uKQpsaWJyYXJ5KGdnYnJlYWspCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGdnaDR4KQpsaWJyYXJ5KGdndGV4dCkKbGlicmFyeShkcmMpCmBgYAoKIyBGaWd1cmUgMTogQ29iYWx0IGNvcnJvc2lvbiBkYXRhIGZvciB3aWxkIHR5cGUgY2VsbHMsIOKIhnBoeiBtdXRhbnRzLCBzcGVudCBtZWRpdW0sIGFuZCBhYmlvdGljIGNvbnRyb2xzIGluIHN0ZXJpbGUgbWVkaXVtCgoxLiBVc2UgdGhlIGNvZGUgYmVsb3cgdG8gbG9hZCBpbiBzb3VyY2UgZGF0YS4KYGBge3J9CkFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCA8LSBmcmVhZCgiQWxsX2NvYmFsdF9JQ1BNU19kYXRhX2NsZWFuZWRfZm9ybWF0dGVkXzIwMjUwNTEzLnR4dCIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikKYGBgCgoyLiBVc2UgdGhlIGNvZGUgYmVsb3cgdG8gZ2VuZXJhdGUgdGhlIHNjYXR0ZXJwbG90IGNvbnRhaW5pbmcgdGhlIGNhdGVnb3JpZXMgb2YgaW50ZXJlc3QuCmBgYHtyfQojQWRqdXN0IHRoZSBwcmVzZW50YXRpb24gYWVzdGhldGljcwp0aGVtZTwtIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzIsIGFuZ2xlID0gMCwgaGp1c3QgPSAuNSwgdmp1c3QgPSAuNSwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzMiwgYW5nbGUgPSAwLCBoanVzdCA9IDEsIHZqdXN0ID0gMCwgZmFjZSA9ICJwbGFpbiIpLCAgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzNCwgYW5nbGUgPSAwLCBoanVzdCA9IC41LCB2anVzdCA9IDAsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzQsIGFuZ2xlID0gOTAsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMzIsIGNvbG91ciA9ICJncmV5MjAiLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMyLCBjb2xvdXIgPSAiZ3JleTIwIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMzAsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gLjUpLAogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0zMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTMyKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkKCiNDcmVhdGUgY3VzdG9tIGRpc3BsYXkgb3JkZXJzCkFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihBbGxfY29iYWx0X2RhdGFfY29tYmluZWQkQWJpb3RpY192c19iaW90aWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAi4oiGcGh6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwZW50IG1lZGl1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKQoKQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkJE1ldGFib2xpdGVfdHJlYXRtZW50X29yZGVyZWQgPC0gZmFjdG9yKEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRNZXRhYm9saXRlX3RyZWF0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJOb3RoaW5nIGFkZGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lT0giKSkKI0dyYXBoaW5nIHNjcmlwdCB3aXRoIGFkZGl0aW9uYWwgZGF0YSBtYW5pcHVsYXRpb24KbGlicmFyeSh3ZXNhbmRlcnNvbikKQWJpb3RpY192c19iaW90aWNfdHJlYXRtZW50X3NjYXR0ZXJwbG90IDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JSAjMjE2IG9ic2VydmF0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoQWJpb3RpY192c19iaW90aWMsIFdpcmVfdHJlYXRtZW50LCBETVNPX3RyZWF0bWVudCwgTWV0YWJvbGl0ZV90cmVhdG1lbnQsIFRpbWUpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IG1lYW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wgPSBtZWRpYW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RkZXZfY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IHNkKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pbl9jb2JhbHRfY29uY2VudHJhdGlvbl91Z19MID0gbWluKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heF9jb2JhbHRfY29uY2VudHJhdGlvbl91Z19MID0gbWF4KENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0gPSBtZWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWRpYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0gPSBtZWRpYW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gc2QoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pbl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSA9IG1pbihDb2JhbHRfY29uY2VudHJhdGlvbl91TSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gbWF4KENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxvY2F0ZShNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0w6TWF4X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLCAuYWZ0ZXIgPSBDb2JhbHRfY29uY2VudHJhdGlvbl91TSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIUJvdHRsZV9udW1iZXIgPT0gIjEiKSAlPiUgI3JlbW92ZSBvdXRsaWVyIHN0ZXJpbGUgY29udHJvbAoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI3Bsb3R0aW5nIHNjcmlwdAogICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1UaW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSBNZXRhYm9saXRlX3RyZWF0bWVudF9vcmRlcmVkKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDYpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSAtIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHltYXggPSBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNICsgU3RkZXZfY29iYWx0X2NvbmNlbnRyYXRpb25fdU0pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IEJvdHRsZV9udW1iZXIsIGNvbG9yID0gQWJpb3RpY192c19iaW90aWNfb3JkZXJlZCkpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTY4LCBieSA9IDI0KSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0X2dyaWQofiBXaXJlX3RyZWF0bWVudCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIoIkNvYmFsdFxuY29uY2VudHJhdGlvbiAowrVNKSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiKCJUaW1lIGVsYXBzZWQgKGhvdXJzKSIpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiQWJpb3RpYyB2cyBiaW90aWMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcxIiwgbiA9IDQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaWxkIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbihpdGFsaWMoIuKIhnBoeiIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwZW50IG1lZGl1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShuYW1lID0gIk1ldGFib2xpdGUgdHJlYXRtZW50IikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gLTIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpKQogICAgICAgICAgCiNBZGQgYSBsYXllciB0byBhbmdsZSB0aGUgdGV4dApBYmlvdGljX3ZzX2Jpb3RpY190cmVhdG1lbnRfc2NhdHRlcnBsb3RfYW5nbGVkIDwtIEFiaW90aWNfdnNfYmlvdGljX3RyZWF0bWVudF9zY2F0dGVycGxvdCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQoKI1NhdmUgaW4gZGlmZmVyZW50IGltYWdlIGZvcm1hdHMgYXQgMzAwIGRwaQpnZ3NhdmUoIkZpZzFfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY19iaW90aWNfYW5kX21ldGFib2xpdGVfdHJlYXRtZW50c19ub19ETVNPX3NjYXR0ZXJwbG90X2FuZ2xlZC5qcGciLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMiwgZGV2aWNlPSBqcGVnKQpnZ3NhdmUoIkZpZzFfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY19iaW90aWNfYW5kX21ldGFib2xpdGVfdHJlYXRtZW50c19ub19ETVNPX3NjYXR0ZXJwbG90X2FuZ2xlZC50aWZmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjIsIGRldmljZT0gdGlmZikKZ2dzYXZlKCJGaWcxX0NvYmFsdF9JQ1BNU19kYXRhX2FiaW90aWNfYmlvdGljX2FuZF9tZXRhYm9saXRlX3RyZWF0bWVudHNfbm9fRE1TT19zY2F0dGVycGxvdF9hbmdsZWQucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjIsIGRldmljZT0gY2Fpcm9fcGRmKQpgYGAKCgojIEZpZ3VyZSBTMTogQU5PVkEgdGVzdCBvbiBjb2JhbHQgY29uY2VudHJhdGlvbnMgc2FtcGxlZCBhdCAxNjggaG91cnMgaW4gYmlvdGljIHZzIGFiaW90aWMgdHJlYXRtZW50cyB3aXRoIGFuZCB3aXRob3V0IG1hc3MgYmFsYW5jZSBjb3JyZWN0aW9uCgojIyBGaWd1cmUgUzFBOiBBTk9WQSB0ZXN0IHdpdGhvdXQgcmVjb3ZlcmllcyBhcHBsaWVkCgoxLiBMb2FkIHRoZSBjb2JhbHQgZGF0YSBhbmQgdHJpbSBpdCB3aGVyZSB0aGUgd2lyZSB3YXMgc3VwcGxpZWQuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgPC0gZnJlYWQoIkFsbF9jb2JhbHRfSUNQTVNfZGF0YV9jbGVhbmVkX2Zvcm1hdHRlZF8yMDI1MDUxMy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCgpBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YSA8LSBBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNhbXBsZV9wcmVzZXJ2YXRpb24gPT0gIkFjaWRpZmllZCwgZmlsdGVyZWQiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihUaW1lID09IDE2OCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihNZXRhYm9saXRlX3RyZWF0bWVudCA9PSAiTm90aGluZyBhZGRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAjMjQgb2JzZXJ2YXRpb25zCmBgYAoKMi4gR2VuZXJhdGUgdGhlIEFOT1ZBIG1vZGVsIHdpdGggdHlwZSBJSUkgc3VtIG9mIHNxdWFyZXMgdG8gYWNjb3VudCBmb3IgdGhlIHVuYmFsYW5jZWQgZGVzaWduIGFuZCBpbnRlcnByZXQgdmlzdWFsaXphdGlvbnMgZm9yIGxpbmVhciBtb2RlbCBhc3N1bXB0aW9ucwpgYGB7cn0KQWJpb3RpY192c19iaW90aWNfbW9kZWwgPC0gbG0oQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0gfiBBYmlvdGljX3ZzX2Jpb3RpYywgZGF0YSA9IEFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9BTk9WQV9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhc3RzID0gbGlzdChBYmlvdGljX3ZzX2Jpb3RpYyA9IGNvbnRyLnN1bSksIHR5cGUgPTMpCgpBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbApwYXIobWZyb3cgPSBjKDIsMikpCnBsb3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwpCgojUnVuIEJyZXVzY2ggUGFnYW4gdGVzdCBmb3IgaG9tb3NjZWRhc3RpY2l0eQpicHRlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwpCgojUnVuIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwkcmVzaWR1YWxzKQoKI1J1biBEdXJiaW4tV2F0c29uIHRlc3QgZm9yIGF1dG9jb3JyZWxhdGlvbgpkd3Rlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwpCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gSG9tb3NjZWRhc3RpY2l0eSBsb29rcyBsaWtlIGl0IG1heSBiZSBhIHNsaWdodCBpc3N1ZSBlc3BlY2lhbGx5IGFzIGNvYmFsdCBjb25jZW50cmF0aW9ucyBnZXQgaGlnaGVyLgotIFRoZXJlIGFyZSBhIGZldyBzbGlnaHRseSBwcm9ibGVtYXRpYyB2YWx1ZXMgb24gdGhlIFEtUSByZXNpZHVhbHMgcGxvdCB0aGF0IG1heSBuZWVkIHRvIGJlIGFkZHJlc3NlZCB3aXRoIGEgbG9nIHRyYW5zZm9ybSAodmFsdWUgNiBpbiBwYXJ0aWN1bGFyKS4KLSBCUCB0ZXN0IHJldHVybnMgYSBwLXZhbHVlIG9mICowLjAzOTczKiwgc28gd2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaG9tb3NjZWRhc3RpY2l0eSAoYXMgZXhwZWN0ZWQpLgotIFNXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgKjAuMzUxNiosIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCi0gRFcgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC4zMjk1Kiwgc28gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlcmUgaXMgbm8gYXV0b2NvcnJlbGF0aW9uIGJldHdlZW4gZGF0YSBwb2ludHMuCgoyLiBSZS1ydW4gdGhlIG1vZGVsIHdpdGggYSBsb2cxMCB0cmFuc2Zvcm0gdG8gYWRkcmVzcyB0aGUgaXNzdWVzIGFzc29jaWF0ZWQgd2l0aCBob21vc2NlZGFzdGljaXR5LgpgYGB7cn0KQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTAgPC0gbG0obG9nMTAoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pIH4gQWJpb3RpY192c19iaW90aWMsIGRhdGEgPSBBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYXN0cyA9IGxpc3QoQWJpb3RpY192c19iaW90aWMgPSBjb250ci5zdW0pLCB0eXBlID0zKQoKQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTAKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwKQoKI1J1biBCcmV1c2NoIFBhZ2FuIHRlc3QgZm9yIGhvbW9zY2VkYXN0aWNpdHkKYnB0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwKQoKI1J1biBTaGFwaXJvLVdpbGsgbm9ybWFsaXR5IHRlc3QKc2hhcGlyby50ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwKQpgYGAKIyMjIEludGVycHJldGF0aW9uCi0gSG9tb3NjZWRhc3RpY2l0eSBsb29rcyBsaWtlIGl0IHdpa2xsIGJlIGxlc3Mgb2YgYW4gaXNzdWUsIGFsdGhvdWdoIG5vdyB2YWx1ZSBwb2ludCAxLCB0aGUgb3V0bGllciwgaXMgcHJvYmxlbWF0aWMuCi0gQlAgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC40MjE3Kiwgc28gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHkuCi0gU1cgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC4wNDcyNSosIHNvIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgcmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZC4KLSBEVyB0ZXN0IHJldHVybnMgYSBwLXZhbHVlIG9mICowLjA3MzYqLCBzbyB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGVyZSBpcyBubyBhdXRvY29ycmVsYXRpb24gYmV0d2VlbiBkYXRhIHBvaW50cy4KClRoZSBpc3N1ZSB3aXRoIHRoZSBwb3RlbnRpYWwgb3V0bGllciBpcyBiYWNrLiBUaGlzIHdhcyBhIGNvbnRhbWluYXRlZCBzdGVyaWxlIGNvbnRyb2wsIHNvIHRoZXJlIGlzIGEgKmJpb2xvZ2ljYWwqIHJlYXNvbiB0byByZW1vdmUgaXQgZnJvbSBjb25zaWRlcmF0aW9uLgoKMy4gUmUtcnVuIHRoZSBtb2RlbCByZW1vdmluZyB0aGUgb3V0bGllciBhbmQgdGhlbiBsb2cxMC10cmFuc2Zvcm1pbmcgdGhlIGRhdGEgdG8gYWRkcmVzcyBpc3N1ZXMgb2Ygbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiByZXNpZHVhbHMuCmBgYHtyfQpBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YV9vdXRsaWVyX3JlbW92ZWQgPC0gQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKERNU09fdHJlYXRtZW50ID09ICJObyBETVNPIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNhbXBsZV9wcmVzZXJ2YXRpb24gPT0gIkFjaWRpZmllZCwgZmlsdGVyZWQiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoVGltZSA9PSAxNjgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKE1ldGFib2xpdGVfdHJlYXRtZW50ID09ICJOb3RoaW5nIGFkZGVkIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighU2FtcGxlX25hbWUgPT0gIjIwMjQtMDItMjBfMTY4aHJfV2lyZStNZWRpYV8xX0EtRiIpICNzdXNwZWN0ZWQgb3V0bGllcgoKIyNHZW5lcmF0ZSBtb2RlbApBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQgPC0gbG0obG9nMTAoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pIH4gQWJpb3RpY192c19iaW90aWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9BTk9WQV9kYXRhX291dGxpZXJfcmVtb3ZlZCAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhc3RzID0gbGlzdChBYmlvdGljX3ZzX2Jpb3RpYyA9IGNvbnRyLnN1bSksIHR5cGUgPTMpCgpBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZCkKCiNSdW4gQnJldXNjaCBQYWdhbiB0ZXN0IGZvciBob21vc2NlZGFzdGljaXR5CmJwdGVzdChBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQpCgojUnVuIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZCkKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KLSBIb21vc2NlZGFzdGljaXR5IGxvb2tzIG9rYXkgYXMgZG9lcyB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiByZXNpZHVhbHMuCi0gQlAgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAwLjQzNTUsIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBob21vc2NlZGFzdGljaXR5LgotIFNXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgMC43NzUxLCBzbyB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgotIERXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgMC4zMzk1LCBzbyB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGVyZSBpcyBubyBhdXRvY29ycmVsYXRpb24gYmV0d2VlbiBkYXRhIHBvaW50cy4KCioqQWxsIGxpbmVhciBtb2RlbCBhc3N1bXB0aW9ucyBhcmUgbWV0KioKCjQuIEdlbmVyYXRlIHRoZSBvdXRwdXQgb2YgYW5vdmEgbW9kZWwgZ2VuZXJhdGVkIHdpdGggdGhlIGRhdGEgd2hlcmUgdGhlIG91dGxpZXIgcmVtb3ZlZCBhbmQgYSBsb2cxMCB0cmFuc2Zvcm1hdGlvbiB3YXMgYXBwbGllZC4gVGhpcyBpcyByZXR1cm5pbmcgYSB0eXBlIDIgc3VtIG9mIHNxdWFyZXMgYmVjYXVzZSB3ZSBhcmUgbm8gbG9uZ2VyIGNvbnNpZGVyaW5nIHRoZSBpbnRlcmFjdGlvbiBoYXZpbmcgY29udHJvbGxlZCBmb3Igd2lyZSB0cmVhdG1lbnQKYGBge3J9CkFiaW90aWNfdnNfYmlvdGljX3R5cGVfSUlfQU5PVkFfcmVzdWx0cyA8LSBBbm92YShBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQsIHR5cGUgPSAzKQpBYmlvdGljX3ZzX2Jpb3RpY190eXBlX0lJX0FOT1ZBX3Jlc3VsdHMKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KLSBUaGVyZSBhcmUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gY29iYWx0IGNvbmNlbnRyYXRpb24gYXQgMTY4IGhvdXJzIHRoYXQgYXJlIGF0dHJpYnV0YWJsZSB0byB0aGUgZGlmZmVyZW50IGFiaW90aWMgdnMgYmlvdGljIHRyZWF0bWVudHMuCgo1LiBSdW4gYSBUdWtleSBwb3N0LWhvYyB0ZXN0IHRvIGlkZW50aWZ5IHdoZXJlIHRoZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBvY2N1ciBiZXR3ZWVuIHRyZWF0bWVudHMKYGBge3J9CiNGaXJzdCB5b3UgbmVlZCB0byBjb252ZXJ0IHRoZSBtb2RlbCB0byBhbiBhb3Ygb2JqZWN0CkFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9jb252ZXJ0ZWQgPC0gYW92KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZCkKVHVrZXlfY29tcGFyaXNvbl9hYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQgPC0gVHVrZXlIU0QoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX2NvbnZlcnRlZCwgY29uZi5sZXZlbCA9IDAuOTUpClR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkClR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfZGF0YV9mcmFtZSA8LSBhcy5kYXRhLmZyYW1lKFR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkJEFiaW90aWNfdnNfYmlvdGljKQoKd3JpdGUudGFibGUoVHVrZXlfY29tcGFyaXNvbl9hYmlvdGljX3ZzX2Jpb3RpY19kYXRhX2ZyYW1lLCAKICAgICAgICAgICAgZmlsZSA9ICJUdWtleV9jb21wYXJpc29uX3Jlc3VsdHNfYWJpb3RpY192c19iaW90aWNfbG9nMTBfb3V0bGllcl9yZW1vdmVkXzIwMjUwNDAxLnR4dCIsIHNlcCA9ICJcdCIsIAogICAgICAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSkgCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW46CiAgLSBTcGVudCBtZWRpdW0gdnMg4oiGcGh6CiAgLSBTdGVyaWxlIG1lZGl1bSB2cyDiiIZwaHoKICAtIFN0ZXJpbGUgbWVkaXVtIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHN0ZXJpbGUgbWVkaXVtCi0gVGhlIG9ubHkgbm9uLXNpZ25pZmljYW50IGRpZmZlcmVuY2UgaXMgYmV0d2VlbiB3aWxkIHR5cGUgYW5kIOKIhnBoegotIExldHRlcnMgdG8gYWRkIHRvIHBsb3RzOgogIC0gV2lsZCB0eXBlOiBBCiAgLSDiiIZwaHo6IEEKICAtIFNwZW50IG1lZGl1bTogQgogIC0gU3RlcmlsZSBtZWRpdW06IEMKCjYuIEdlbmVyYXRlIGJveHBsb3RzIHRoYXQgd2lsbCBiZSB1c2VkIHRvIG92ZXJsYXkgdGhlIFR1a2V5IGFubm90YXRpb25zIG1hbnVhbGx5IGluIGFuIGltYWdlIGVkaXRvcgpgYGB7cn0KdGhlbWU8LSB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDAsIGhqdXN0ID0gMC41LCB2anVzdCA9IDAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTYsIGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJwbGFpbiIpLCAgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIHNpemUgPSAxOCwgYW5nbGUgPSAwLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTgsIGFuZ2xlID0gOTAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBjb2xvdXIgPSAiZ3JleTIwIiksCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgY29sb3VyID0gImdyZXkyMCIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTgpLCAKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkKCiNDcmVhdGUgY3VzdG9tIG9yZGVyIHRvIGRpc3BsYXkgeC1heGlzCgpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQkQWJpb3RpY192c19iaW90aWNfb3JkZXJlZCA8LSBmYWN0b3IoQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkJEFiaW90aWNfdnNfYmlvdGljLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiV2lsZCB0eXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIuKIhnBoeiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVudCBtZWRpdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3RlcmlsZSBtZWRpdW0iKSkKCkFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9ib3hwbG90X2xvZzEwIDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKERNU09fdHJlYXRtZW50ID09ICJObyBETVNPIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFRpbWUgPT0gMTY4KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKE1ldGFib2xpdGVfdHJlYXRtZW50ID09ICJOb3RoaW5nIGFkZGVkIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXaXJlX3RyZWF0bWVudCA9PSAiV2lyZSBpbmNsdWRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIVNhbXBsZV9uYW1lID09ICIyMDI0LTAyLTIwXzE2OGhyX1dpcmUrTWVkaWFfMV9BLUYiKSAlPiUgI3N1c3BlY3RlZCBvdXRsaWVyCiAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjR3JhcGhpbmcgc2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1BYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkLCB5PWxvZzEwKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSkpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fYm94cGxvdCgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9qaXR0ZXIoZmlsbCA9ICJncmV5IiwgY29sb3VyID0gImJsYWNrIiwgd2lkdGggPSAwLjEsIHBjaCA9MjEsIHN0cm9rZSA9MSkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oMCwgMy41KSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZSA9ICIiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gImxvZzEwKENvYmFsdCBjb25jZW50cmF0aW9uICjCtU0pKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiQWJpb3RpYyBhbmQgYmlvdGljIHRyZWF0bWVudHMiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lICsgI3RoaXMgY2FsbHMgdGhlIGFlc3RoZXRpYyB0aGVtZSB2YXJpYWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMikpCgpBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfYm94cGxvdF9sb2cxMCAjYW5vdGF0ZSB0aGlzIG1hbnVhbGx5IGluIGFuIGltYWdlIGVkaXRvcgoKI1NhdmUgZmlsZXMgaW4gZGlmZmVyZW50IGZvcm1hdHMKZ2dzYXZlKCJGaWdTMUFfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwXzIwMjUwNTE0LmpwZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTYsIHdpZHRoPTksIGRldmljZT0ganBlZykKZ2dzYXZlKCJGaWdTMUFfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwXzIwMjUwNTE0LnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD05LCBkZXZpY2U9IHRpZmYpCmdnc2F2ZSgiRmlnUzFBX0NvYmFsdF9JQ1BNU19kYXRhX2Jpb3RpY190cmVhdG1lbnRzX25vX0RNU09fYm94cGxvdF9sb2cxMF8yMDI1MDUxNC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD05LCBkZXZpY2U9Y2Fpcm9fcGRmKQpgYGAKCiMjIEZpZyBTMUI6IEFOT1ZBIHRlc3Qgd2l0aCBtYXNzIGJhbGFuY2UgcmVjb3ZlcmllcyBhcHBsaWVkCjEuIExvYWQgaW4gdGhlIGRhdGEgZnJvbSB0aGUgbWFudWFsbHkgYWRqdXN0ZWQgdGFiLWRlbGltaXRlZCBmaWxlIHRoYXQgY29udGFpbnMgcmVjb3Zlcmllcy4gR2VuZXJhdGUgYSBuZXcgdmFyaWFibGUgd2hlcmUgdGhlIHJlY292ZXJ5IGhhcyBiZWVuIGFwcGxpZWQuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyA8LSBmcmVhZCgiQWxsX2NvYmFsdF9JQ1BNU19kYXRhX2NsZWFuZWRfZm9ybWF0dGVkXzIwMjUwNTEzLnR4dCIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShDb2JhbHRfY29uY2VudHJhdGlvbl91TV9jb3JyZWN0ZWQgPSBDb2JhbHRfY29uY2VudHJhdGlvbl91TS9SZWNvdmVyeSkgJT4lICNhcHBseSByZWNvdmVyaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbG9jYXRlKENvYmFsdF9jb25jZW50cmF0aW9uX3VNX2NvcnJlY3RlZCwgLmFmdGVyID0gQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pCmBgYAoKMi4gUnVuIHRoZSBtb2RlbCBhcHBseWluZyB0aGUgc2FtZSBvdXRsaWVyIHJlbW92YWwgYW5kIGxvZy10cmFuc2Zvcm1hdGlvbnMgdXNlZCBvbiB0aGUgZGF0YSB0aGF0IHdhcyBub3QgY29ycmVjdGVkIGZvciByZWNvdmVyeS4KYGBge3J9CkFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9BTk9WQV9kYXRhX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzIDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZF9yZWNvdmVyaWVzICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoRE1TT190cmVhdG1lbnQgPT0gIk5vIERNU08iKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihTYW1wbGVfcHJlc2VydmF0aW9uID09ICJBY2lkaWZpZWQsIGZpbHRlcmVkIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoVGltZSA9PSAxNjgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoTWV0YWJvbGl0ZV90cmVhdG1lbnQgPT0gIk5vdGhpbmcgYWRkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFdpcmVfdHJlYXRtZW50ID09ICJXaXJlIGluY2x1ZGVkIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighU2FtcGxlX25hbWUgPT0gIjIwMjQtMDItMjBfMTY4aHJfV2lyZStNZWRpYV8xX0EtRiIpCgojI0dlbmVyYXRlIG1vZGVsCkFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzIDwtIGxtKGxvZzEwKENvYmFsdF9jb25jZW50cmF0aW9uX3VNX2NvcnJlY3RlZCkgfiBBYmlvdGljX3ZzX2Jpb3RpYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YV9vdXRsaWVyX3JlbW92ZWRfcmVjb3ZlcmllcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYXN0cyA9IGxpc3QoQWJpb3RpY192c19iaW90aWMgPSBjb250ci5zdW0pLCB0eXBlID0zKQoKQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzKQoKI1J1biBCcmV1c2NoIFBhZ2FuIHRlc3QgZm9yIGhvbW9zY2VkYXN0aWNpdHkKYnB0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzKQoKI1J1biBTaGFwaXJvLVdpbGsgbm9ybWFsaXR5IHRlc3QKc2hhcGlyby50ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzKQpgYGAKCiMjIyBJbnRlcnByZXRhdGlvbgotIEhvbW9zY2VkYXN0aWNpdHkgbG9va3Mgb2theSBhcyBkb2VzIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIG9mIHJlc2lkdWFscy4KLSBCUCB0ZXN0IHJldHVybnMgYSBwLXZhbHVlIG9mIDAuNDM1NSwgc28gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHkuCi0gU1cgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAwLjc3NTEsIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCi0gRFcgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAwLjMzOTUsIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZXJlIGlzIG5vIGF1dG9jb3JyZWxhdGlvbiBiZXR3ZWVuIGRhdGEgcG9pbnRzLgoKKipBbGwgbGluZWFyIG1vZGVsIGFzc3VtcHRpb25zIGFyZSBtZXQqKgoKMy4gR2VuZXJhdGUgdGhlIGFjdHVhbCBvdXRwdXQgb2YgYW5vdmEgbW9kZWwgZ2VuZXJhdGVkIHdpdGggdGhlIGRhdGEgd2hlcmUgdGhlIG91dGxpZXIgcmVtb3ZlZCBhbmQgYSBsb2cxMCB0cmFuc2Zvcm1hdGlvbiB3YXMgYXBwbGllZC4gVGhpcyBpcyByZXR1cm5pbmcgYSB0eXBlIDIgc3VtIG9mIHNxdWFyZXMgYmVjYXVzZSB3ZSBhcmUgbm90IGxvbmdlciBjb25zaWRlcmluZyB0aGUgaW50ZXJhY3Rpb24gaGF2aW5nIGNvbnRyb2xsZWQgZm9yIHdpcmUgdHJlYXRtZW50CmBgYHtyfQpBYmlvdGljX3ZzX2Jpb3RpY190eXBlX0lJX0FOT1ZBX3Jlc3VsdHNfcmVjb3ZlcmllcyA8LSBBbm92YShBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWRfcmVjb3ZlcmllcywgdHlwZSA9IDMpCkFiaW90aWNfdnNfYmlvdGljX3R5cGVfSUlfQU5PVkFfcmVzdWx0c19yZWNvdmVyaWVzCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGluIGNvYmFsdCBjb25jZW50cmF0aW9uIGF0IDE2OCBob3VycyB0aGF0IGFyZSBhdHRyaWJ1dGFibGUgdG8gdGhlIGRpZmZlcmVudCBhYmlvdGljIHZzIGJpb3RpYyB0cmVhdG1lbnRzIGV2ZW4gYWZ0ZXIgY29ycmVjdGluZyBmb3IgcmVjb3Zlcmllcy4KLSBUaGUgcC12YWx1ZXMgYXJlIGRpZmZlcmVudCBmb3IgdGhlIHJlY292ZXJ5IGNvcnJlY3RlZCBkYXRhLCBidXQgYm90aCB2ZXJzaW9uIG9mIHRoZSBkYXRhIGhhdmUgcCA8IDAuMDAxLgoKNC4gUnVuIGEgVHVrZXkgcG9zdC1ob2MgdGVzdCB0byBmaWd1cmUgb3V0IHdoZXJlIHRoZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBhcmUuCmBgYHtyfQpsaWJyYXJ5KGRhdGEudGFibGUpCiNGaXJzdCB5b3UgbmVlZCB0byBjb252ZXJ0IHRoZSBtb2RlbCB0byBhbiBhb3Ygb2JqZWN0CkFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9jb252ZXJ0ZWRfcmVjb3ZlcmllcyA8LSBhb3YoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMpClR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMgPC0gVHVrZXlIU0QoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX2NvbnZlcnRlZF9yZWNvdmVyaWVzLCBjb25mLmxldmVsID0gMC45NSkKVHVrZXlfY29tcGFyaXNvbl9hYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWRfcmVjb3ZlcmllcwpUdWtleV9jb21wYXJpc29uX2FiaW90aWNfdnNfYmlvdGljX2RhdGFfZnJhbWVfcmVjb3ZlcmllcyA8LSBhcy5kYXRhLmZyYW1lKFR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMkQWJpb3RpY192c19iaW90aWMpCgp3cml0ZS50YWJsZShUdWtleV9jb21wYXJpc29uX2FiaW90aWNfdnNfYmlvdGljX2RhdGFfZnJhbWVfcmVjb3ZlcmllcywgCiAgICAgICAgICAgIGZpbGUgPSAiVHVrZXlfY29tcGFyaXNvbl9yZXN1bHRzX2FiaW90aWNfdnNfYmlvdGljX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzXzIwMjUwNTEzLnR4dCIsIHNlcCA9ICJcdCIsIAogICAgICAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSkgCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW46CiAgLSBTcGVudCBtZWRpdW0gdnMg4oiGcGh6CiAgLSBTdGVyaWxlIG1lZGl1bSB2cyDiiIZwaHoKICAtIFN0ZXJpbGUgbWVkaXVtIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHN0ZXJpbGUgbWVkaXVtCi0gVGhlIG9ubHkgbm9uLXNpZ25pZmljYW50IGRpZmZlcmVuY2UgaXMgYmV0d2VlbiB3aWxkIHR5cGUgYW5kIOKIhnBoegotIEV4cGVjdGVkIGxldHRlcnMKICAtIFdpbGQgdHlwZTogQQogIC0g4oiGcGh6OiBBCiAgLSBTcGVudCBtZWRpdW06IEIKICAtIFN0ZXJpbGUgbWVkaXVtOiBDCgo1LiBSZWdlbmVyYXRlIGJveHBsb3RzIHRoYXQgd2lsbCBiZSB1c2VkIHRvIG92ZXJsYXkgdGhlIFR1a2V5IGFubm90YXRpb25zIG1hbnVhbGx5LgpgYGB7cn0KdGhlbWU8LSB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDAsIGhqdXN0ID0gMC41LCB2anVzdCA9IDAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTYsIGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJwbGFpbiIpLCAgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIHNpemUgPSAxOCwgYW5nbGUgPSAwLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTgsIGFuZ2xlID0gOTAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBjb2xvdXIgPSAiZ3JleTIwIiksCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgY29sb3VyID0gImdyZXkyMCIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTgpLCAKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkKCiNDcmVhdGUgY3VzdG9tIG9yZGVyIHRvIGRpc3BsYXkgeC1heGlzCgpBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyRBYmlvdGljX3ZzX2Jpb3RpYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIuKIhnBoeiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BlbnQgbWVkaXVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKQoKQWJpb3RpY192c19iaW90aWNfd2lyZV9vbmx5X2JveHBsb3RfbG9nMTBfcmVjb3ZlcmllcyA8LSBBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoRE1TT190cmVhdG1lbnQgPT0gIk5vIERNU08iKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNhbXBsZV9wcmVzZXJ2YXRpb24gPT0gIkFjaWRpZmllZCwgZmlsdGVyZWQiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFRpbWUgPT0gMTY4KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoTWV0YWJvbGl0ZV90cmVhdG1lbnQgPT0gIk5vdGhpbmcgYWRkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIVNhbXBsZV9uYW1lID09ICIyMDI0LTAyLTIwXzE2OGhyX1dpcmUrTWVkaWFfMV9BLUYiKSAlPiUgI3N1c3BlY3RlZCBvdXRsaWVyCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjR3JhcGhpbmcgc2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PUFiaW90aWNfdnNfYmlvdGljX29yZGVyZWQsIHk9bG9nMTAoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU1fY29ycmVjdGVkKSkpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21faml0dGVyKGZpbGwgPSAiZ3JleSIsIGNvbG91ciA9ICJibGFjayIsIHdpZHRoID0gMC4xLCBwY2ggPTIxLCBzdHJva2UgPTEpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oMCwgMy41KSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHRpdGxlID0gIiIgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJsb2cxMChDb2JhbHQgY29uY2VudHJhdGlvbiAowrVNKVxuY29ycmVjdGVkIGZvciByZWNvdmVyeSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiQWJpb3RpYyBhbmQgYmlvdGljIHRyZWF0bWVudHMiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgKyAjdGhpcyBjYWxscyB0aGUgYWVzdGhldGljIHRoZW1lIHZhcmlhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQodmp1c3QgPSAyKSkKCkFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9ib3hwbG90X2xvZzEwX3JlY292ZXJpZXMgI2Fub3RhdGUgdGhpcyBtYW51YWxseSBpbiBhbiBpbWFnZSBlZGl0b3IKZ2dzYXZlKCJGaWdTMUJfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwX3JlY292ZXJpZXNfYXBwbGllZF8yMDI1MDUxMy5qcGciLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD05LCBkZXZpY2U9anBlZykKZ2dzYXZlKCJGaWdTMUJfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwX3JlY292ZXJpZXNfYXBwbGllZF8yMDI1MDUxMy4udGlmZiIsIGRwaSA9IDMwMCwgaGVpZ2h0PTYsIHdpZHRoPTksIGRldmljZT10aWZmKQpnZ3NhdmUoIkZpZ1MxQl9Db2JhbHRfSUNQTVNfZGF0YV9iaW90aWNfdHJlYXRtZW50c19ub19ETVNPX2JveHBsb3RfbG9nMTBfcmVjb3Zlcmllc19hcHBsaWVkXzIwMjUwNTEzLnBkZiIsIGRwaSA9IDMwMCwgaGVpZ2h0PTYsIHdpZHRoPTksIGRldmljZT1jYWlyb19wZGYpCmBgYAoKCiMgRmlndXJlIFMyOiBBTk9WQSB0ZXN0IG9uIGFiaW90aWMgY29udHJvbHMgd2l0aCBhbmQgd2l0aG91dCBwaGVuYXppbmUtMS1jYXJib3h5bGljIGFjaWQKCjEuIExvYWQgdGhlIGRhdGEgZnJhbWUgZnJvbSB0aGUgY29tcGlsZWQgZGF0YSBhbmQgcmVtb3ZlIHRoZSBvdXRsaWVyIHZhbHVlIGZyb20gdGhlIHN0ZXJpbGUgbWVkaXVtIHRyZWF0bWVudCB0aGF0IHdhcyBjb250YW1pbmF0ZWQuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgPC0gZnJlYWQoIkFsbF9jb2JhbHRfSUNQTVNfZGF0YV9jbGVhbmVkX2Zvcm1hdHRlZF8yMDI1MDUxMy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCgojQ3JlYXRlIGN1c3RvbSBvcmRlciBmb3IgeC1heGlzCkFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihBbGxfY29iYWx0X2RhdGFfY29tYmluZWQkQWJpb3RpY192c19iaW90aWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAi4oiGcGh6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwZW50IG1lZGl1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKQoKQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkJE1ldGFib2xpdGVfdHJlYXRtZW50X29yZGVyZWQgPC0gZmFjdG9yKEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRNZXRhYm9saXRlX3RyZWF0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJOb3RoaW5nIGFkZGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lT0giKSkKQWJpb3RpY19ub19vdXRsaWVyIDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JSAjMjE2IG9ic2VydmF0aW9ucwogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFRpbWUgPT0gMTY4ICYgV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAlPiUgI09ubHkgbG9vayBhdCBubyBtZXRhYm9saXRlIHNwaWtlcyArIDE2OCBob3VycwogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKEFiaW90aWNfdnNfYmlvdGljX29yZGVyZWQgPT0gIlN0ZXJpbGUgbWVkaXVtIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIVNhbXBsZV9uYW1lID09ICIyMDI0LTAyLTIwXzE2OGhyX1dpcmUrTWVkaWFfMV9BLUYiKSAjcmVtb3ZlIG91dGxpZXIKYGBgCgoyLiBHZW5lcmF0ZSB0aGUgbGluZWFyIG1vZGVscyBhbmQgdmVyaWZ5IGFzc3VtcHRpb25zIGZvciB0aGUgQU5PVkEgdXNpbmcgdHlwZSBJSUkgc3VtIG9mIHNxdWFyZXMuCmBgYHtyfQojI0dlbmVyYXRlIG1vZGVsCkFiaW90aWNfbW9kZWxfb3V0bGllcl9yZW1vdmVkIDwtIGxtKENvYmFsdF9jb25jZW50cmF0aW9uX3VNIH4gTWV0YWJvbGl0ZV90cmVhdG1lbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gQWJpb3RpY19ub19vdXRsaWVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhc3RzID0gbGlzdChNZXRhYm9saXRlX3RyZWF0bWVudCA9IGNvbnRyLnN1bSksIHR5cGUgPTMpCgpBYmlvdGljX21vZGVsX291dGxpZXJfcmVtb3ZlZApwYXIobWZyb3cgPSBjKDIsMikpCnBsb3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQpCgojUnVuIEJyZXVzY2ggUGFnYW4gdGVzdCBmb3IgaG9tb3NjZWRhc3RpY2l0eQpicHRlc3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQpCgojUnVuIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQkcmVzaWR1YWxzKQoKI1J1biBEdXJiaW4tV2F0c29uIHRlc3QgZm9yIGF1dG9jb3JyZWxhdGlvbgpkd3Rlc3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQpCmBgYAojIyMgSW50ZXJwcmV0YXRpb24KLSBIb21vc2NlZGFzdGljaXR5IG1heSBiZSBhbiBpc3N1ZSwgaXQgbG9va3MgbGlrZSBzYW1wbGVzIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgY29iYWx0IGNvbmNlbnRyYXRpb25zIH4gMjQwIMK1TSBoYXZlIGhpZ2hlciB2YXJpYW5jZS4KLSBOb3JtYWwgZGlzdHJpYnV0aW9uIG9mIHJlc2lkdWFscyBsb29rcyBnb29kLgotIEJQIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgKjAuMjYxMyogLS0+IHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBob21vc2NlZGFzdGljaXR5LgotIFNXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgKjAuMzc1MyogLS0+IHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBub3JtYWxseSBkaXN0cmlidXRlZCByZXNpZHVhbHMuCi0gRFcgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC45MTg4KiAtLT4gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlcmUgaXMgbm8gYXV0b2NvcnJlbGF0aW9uIGJldHdlZW4gZGF0YSBwb2ludHMuCgoqKkFsbCBhc3N1bXB0aW9ucyBtZXQsIG9rYXkgdG8gcHJvY2VlZCB3aXRoIEFOT1ZBKioKCjMuIFJ1biB0aGUgQU5PVkEgYW5kIHRoZSBUdWtleSBjb21wYXJpc29uLgpgYGB7cn0KQWJpb3RpY190eXBlX0lJSV9BTk9WQV9yZXN1bHRzIDwtIEFub3ZhKEFiaW90aWNfbW9kZWxfb3V0bGllcl9yZW1vdmVkLCB0eXBlID0gMykKQWJpb3RpY190eXBlX0lJSV9BTk9WQV9yZXN1bHRzCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gTWV0YWJvbGl0ZSB0cmVhdG1lbnQgZGlkIG5vdCBlbWVyZ2UgYXMgYSBzaWduaWZpY2FudCB2YXJpYWJsZSwgc28gdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgYmV0d2VlbiBncm91cHMuCgo0LiBHZW5lcmF0ZSB0aGUgYm94cGxvdC4gVGhlcmUgaXMgbm8gbmVlZCB0byBhbm5vdGF0ZSB0aGUgYm94ZXMgbGF0ZXIgYmVjYXVzZSB0aGVyZSBhcmUgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuCmBgYHtyfQpBYmlvdGljX291dGxpZXJfcmVtb3ZlZF9ib3hwbG90IDwtIEFiaW90aWNfbm9fb3V0bGllciAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9TWV0YWJvbGl0ZV90cmVhdG1lbnRfb3JkZXJlZCwgeT1Db2JhbHRfY29uY2VudHJhdGlvbl91TSkpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21faml0dGVyKGZpbGwgPSAiZ3JleSIsIGNvbG91ciA9ICJibGFjayIsIHdpZHRoID0gMC4xLCBwY2ggPTIxLCBzdHJva2UgPTEpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oMCwgNDAwKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZSA9ICIiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gIkNvYmFsdCBjb25jZW50cmF0aW9uICjCtU0pIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJNZXRhYm9saWMgdHJlYXRtZW50cyBpbiBzdGVyaWxlIG1lZGl1bSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQodmp1c3QgPSAyKSkKQWJpb3RpY19vdXRsaWVyX3JlbW92ZWRfYm94cGxvdApnZ3NhdmUoIkZpZ1MyX0NvYmFsdF9JQ1BNU19kYXRhX2FiaW90aWNfdHJlYXRtZW50c19ub19ETVNPX2JveHBsb3QuanBnIiwgZHBpID0gMzAwLCBoZWlnaHQ9Niwgd2lkdGg9NiwgZGV2aWNlPWpwZWcpCmdnc2F2ZSgiRmlnUzJfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY190cmVhdG1lbnRzX25vX0RNU09fYm94cGxvdC50aWZmIiwgZHBpID0gMzAwLCBoZWlnaHQ9Niwgd2lkdGg9NiwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnUzJfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY190cmVhdG1lbnRzX25vX0RNU09fYm94cGxvdC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD02LCBkZXZpY2U9Y2Fpcm9fcGRmKQpgYGAKCiMgRmlndXJlIDI6IFBoZW5hemluZSBtZXRhYm9saXRlIGNvbmNlbnRyYXRpb25zIG1lYXN1cmVkIHZpYSBMQy1IUk1TCgoxLiBMb2FkIHRoZSBmb3JtYXR0ZWQgTEMtSFJNUyBkYXRhLgpgYGB7cn0KTENfTVNfZGF0YV9jb21iaW5lZF9sYWJlbGxlZF9sb25nIDwtIGZyZWFkKCJMQ19NU19kYXRhX2NvbWJpbmVkXzIwMjUwNDE5LnR4dCIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikKYGBgCgoyLiBQbG90IHRoZSBzdGFja2VkIGJhciBncmFwaHMgdXNpbmcgdmFyaWFibGVzIHdpdGggYSBjdXN0b20gb3JkZXIuCmBgYHtyfQpiYXJwbG90X3RoZW1lPC0gIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAzMiksCiAgICAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMzIpLAogICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAzNCwgdmp1c3QgPSAtMywgZmFjZSA9ICJib2xkIiksCiAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDM0LCB2anVzdCA9IDYsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAzMiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgICAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDMyLCBmYWNlID0gImJvbGQiKSwKICAgICAgICAgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9NDAsIHZqdXN0ID0gMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgICAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTM0KSwKICAgICAgICAgICAgICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9IE5BKSwKICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA2OCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpLAogICAgICAgICAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBzaXplPTEpLAogICAgICAgICAgICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDIsIDIsIDIsIDIpLCAiY20iKSkKCkxDX01TX2RhdGFfY29tYmluZWRfbGFiZWxsZWRfbG9uZyRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihMQ19NU19kYXRhX2NvbWJpbmVkX2xhYmVsbGVkX2xvbmckQWJpb3RpY192c19iaW90aWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiV2lsZCB0eXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVudCBtZWRpdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIuKIhnBoeiIpKQoKTENfTVNfZGF0YV9jb21iaW5lZF9sYWJlbGxlZF9sb25nJE1ldGFib2xpdGVfb3JkZXJlZCA8LSBmYWN0b3IoTENfTVNfZGF0YV9jb21iaW5lZF9sYWJlbGxlZF9sb25nJE1ldGFib2xpdGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMi1PSFBDQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUENBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyLU9IUEhaIikpCgoKUGhlbmF6aW5lX2JhcnBsb3QgPC0gICBMQ19NU19kYXRhX2NvbWJpbmVkX2xhYmVsbGVkX2xvbmcgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoQ29tbWVudCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKE1lYW5fY29uY2VudHJhdGlvbl91Z19tTCA9IG1lYW4oQ29uY2VudHJhdGlvbl91Z19tTCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD0gVGltZSwgeSA9IENvbmNlbnRyYXRpb25fdWdfbUwsIGZpbGwgPSBNZXRhYm9saXRlX29yZGVyZWQpKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9iYXIoYWVzKGdyb3VwID0gUmVwbGljYXRlKSwgcG9zaXRpb249InN0YWNrIiwgc3RhdD0iaWRlbnRpdHkiKSArCiAgICAgICAgICAgICAgICAgICAgICAgZmFjZXRfbmVzdGVkKFJlcGxpY2F0ZX5XaXJlX3RyZWF0bWVudCArIEFiaW90aWNfdnNfYmlvdGljX29yZGVyZWQpKwogICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTY4LCBieSA9IDI0KSkgKwogICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiTWV0YWJvbGl0ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoIjItT0hQQ0EiID0gIiNGQTFGMUUiLCAgICMgUmVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUENBIiA9ICIjRUJBNjAyIiwgICAgICAgIyBHb2xkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMi1PSFBIWiIgPSAiIzAyN0FCMCIgICAgIyBCbHVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSsKICAgICAgICAgICAgICAgICAgICAgICAjc2NhbGVfZmlsbF9icmV3ZXIobmFtZSA9ICJNZXRhYm9saXRlIiwgcGFsZXR0ZSA9ICJZbE9yUmQiKSsgCiAgICAgICAgICAgICAgICAgICAgICAgeWxpbSgwLDE1KSArCiAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTAuNSksCiAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDI0LCB2anVzdCA9IDApKSsKICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHggPSAiVGltZSBlbGFwc2VkIChob3VycykiICwgeSA9ICJDb25jZW50cmF0aW9uICjCtWcvbUwpIikgKwogICAgICAgICAgICAgICAgICAgICAgIGJhcnBsb3RfdGhlbWUgKyAKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDIsICdjbScpKQoKUGhlbmF6aW5lX2JhcnBsb3QKClBoZW5hemluZV9iYXJwbG90X2FuZ2xlZCA8LSBQaGVuYXppbmVfYmFycGxvdCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMC41KSkKCiNTYXZlIGluIGRpZmZlcmVudCBpbWFnZSBmb3JtYXRzCmdnc2F2ZSgiRmlnMl9waGVuYXppbmVfTENNU19kYXRhX3N0YWNrZWRfYmFycGxvdF9mYWNldGVkLmpwZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTEyLCB3aWR0aD00MCwgZGV2aWNlPWpwZWcpCmdnc2F2ZSgiRmlnMl9waGVuYXppbmVfTENNU19kYXRhX3N0YWNrZWRfYmFycGxvdF9mYWNldGVkLnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD0xMiwgd2lkdGg9NDAsIGRldmljZT10aWZmKQpnZ3NhdmUoIkZpZzJfcGhlbmF6aW5lX0xDTVNfZGF0YV9zdGFja2VkX2JhcnBsb3RfZmFjZXRlZC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD0xMiwgd2lkdGg9NDAsIGRldmljZT1jYWlyb19wZGYpCmBgYAojIEZpZ3VyZSAzOiBXaWxkIHR5cGUgdnMg4oiGcGh6IG11dGFudCBjZWxsIGdyb3d0aCBpbiBjb3Jyb3Npb24gYXNzYXlzCgoxLiBMb2FkIHRoZSBwbGF0ZSBjb3VudCBkYXRhLgpgYGB7cn0KUGxhdGVfY291bnRzX2NvbWJpbmVkIDwtIGZyZWFkKCJQbGF0ZV9jb3VudHNfY29tYmluZWRfMjAyNTA1MjcudHh0Iiwgc2VwID0gIlx0IiwgaGVhZGVyID0gImF1dG8iKQpgYGAKCjIuIEFkZCBuZXcgdmFyaWFibGVzIHRvIHRoZSBkYXRhIGZyYW1lIHBhcnNpbmcgdGhlIENvbW1lbnQgdmFyaWFibGUgdGhhdCBjb250YWlucyBkZXRhaWxlZCBpbmZvcm10aW9uIG9uIHRoZSBzYW1wbGUKYGBge3J9ClBsYXRlX2NvdW50c19jb21iaW5lZF90cmVhdG1lbnRzX2FkZGVkIDwtIFBsYXRlX2NvdW50c19jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0FkZCB0aW1lIGFzIGEgbnVtZXJpYyB2YWlyYWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVGltZSA9IGNhc2Vfd2hlbihncmVwbCgiMGhyIiwgQ29tbWVudCkgfiAiMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCIyNGhyIiwgQ29tbWVudCkgfiAiMjQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiNzJociIsIENvbW1lbnQpIH4gIjcyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIjE2OGhyIiwgQ29tbWVudCkgfiAiMTY4IikpICU+JQogIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVGltZSA9IGFzLm51bWVyaWMoVGltZSkpICU+JQogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjQWRkIHdpcmUgdHJlYXRtZW50IGFzIGEgZGVkaWNhdGVkIHZhcmlhYmxlIGFuZCBsZWF2ZSBhcyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKFdpcmVfdHJlYXRtZW50ID0gY2FzZV93aGVuKGdyZXBsKCJfV2lyZSIsIENvbW1lbnQpIH4gIldpcmUgaW5jbHVkZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIk5vV2lyZSIsIENvbW1lbnQpIH4gIk5vIHdpcmUiKSkgJT4lCiAgCiAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNBZGQgc3RyYWluIGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShTdHJhaW4gPSBjYXNlX3doZW4oZ3JlcGwoIisxMCVpbm9jXyIsIENvbW1lbnQpIH4gIldpbGQgdHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIkRNU08iLCBDb21tZW50KSB+ICJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCIwJWlub2PiiIZwaHoiLCBDb21tZW50KSB+ICLiiIZwaHoiKSkgJT4lCiAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNBZGQgRE1TTyBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoRE1TT190cmVhdG1lbnQgPSBjYXNlX3doZW4oIWdyZXBsKCJETVNPIiwgQ29tbWVudCkgfiAiTm8gRE1TTyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiK0RNU08iLCBDb21tZW50KSB+ICJETVNPIikpIAoKUGxhdGVfY291bnRzX2NvbWJpbmVkX3N1bW1hcnlfc3RhdGlzdGljcyA8LSBQbGF0ZV9jb3VudHNfY29tYmluZWRfdHJlYXRtZW50c19hZGRlZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF9ieShTdHJhaW4sIFdpcmVfdHJlYXRtZW50LCBETVNPX3RyZWF0bWVudCwgRmxhc2tfbnVtYmVyLCBUaW1lKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQ0ZVX21MID4wKSAlPiUgI3JlbW92ZSBhbnkgdmFsdWVzIHRoYXQgaGFkIDAgY291bnRzIG9uIHRoZSBwbGF0ZSBmb3IgZ3JhcGhpbmcKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0NhbGN1bGF0ZSBwbGF0ZSBjb3VudHMgdXNpbmcgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgZm9yIGVhY2ggZmxhc2sgYXQgZWFjaCB0aW1lIHBvaW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKFRlY2huaWNhbF9tZWFuX0NGVV9tTCA9IG1lYW4oQ0ZVX21MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVjaG5pY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKENGVV9tTCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNDYWxjdWxhdGUgcGxhdGUgY291bnRzIHVzaW5nIGF2ZXJhZ2Ugb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgZm9yIGFsbCBmbGFza3MgKGJpb2xvZ2ljYWwgcmVwbGljYXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoU3RyYWluLCBXaXJlX3RyZWF0bWVudCwgRE1TT190cmVhdG1lbnQsIFRpbWUpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKEJpb2xvZ2ljYWxfbWVhbl9DRlVfbUwgPSBtZWFuKFRlY2huaWNhbF9tZWFuX0NGVV9tTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW9sb2dpY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKFRlY2huaWNhbF9tZWFuX0NGVV9tTCkpCgp3cml0ZS50YWJsZShQbGF0ZV9jb3VudHNfY29tYmluZWRfc3VtbWFyeV9zdGF0aXN0aWNzLCBmaWxlID0gIlBsYXRlX2NvdW50c19jb21iaW5lZF9zdW1tYXJ5X3N0YXRpc3RpY3NfMjAyNTA0MTkudHh0Iiwgc2VwID0gIlx0IiwgCiAgICAgICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFKSAKYGBgCgozLiBQbG90IHRoZSBncm93dGggZGF0YSwgc3VtbWFyaXppbmcgdGhlIG1lYW5zIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zIHByaW9yIHRvIHRoZSBnZ3Bsb3QgY29tbWFuZC4KYGBge3J9CiNBZGp1c3QgdGhlIHByZXNlbnRhdGlvbiBhZXN0aGV0aWNzCnRoZW1lPC0gdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzMiwgYW5nbGUgPSAwLCBoanVzdCA9IC41LCB2anVzdCA9IC41LCBmYWNlID0gInBsYWluIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDMyLCBhbmdsZSA9IDAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLCBmYWNlID0gInBsYWluIiksICAKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDM0LCBhbmdsZSA9IDAsIGhqdXN0ID0gLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzNCwgYW5nbGUgPSA5MCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMiwgY29sb3VyID0gImdyZXkyMCIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMzIsIGNvbG91ciA9ICJncmV5MjAiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAuNSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTMyLCBmYWNlID0gImJvbGQiKSwgCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MzIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBzaXplPTEpKQoKI0NyZWF0ZSBjdXN0b20gZGlzcGxheSBvcmRlcnMKUGxhdGVfY291bnRzX2NvbWJpbmVkX3RyZWF0bWVudHNfYWRkZWQkU3RyYWluX29yZGVyZWQgPC0gZmFjdG9yKFBsYXRlX2NvdW50c19jb21iaW5lZF90cmVhdG1lbnRzX2FkZGVkJFN0cmFpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIldpbGQgdHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICLiiIZwaHoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BlbnQgbWVkaXVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN0ZXJpbGUgbWVkaXVtIikpCgoKR3Jvd3RoX2N1cnZlc19sb2dfc2NhbGUgPC0gUGxhdGVfY291bnRzX2NvbWJpbmVkX3RyZWF0bWVudHNfYWRkZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KFN0cmFpbiwgV2lyZV90cmVhdG1lbnQsIERNU09fdHJlYXRtZW50LCBGbGFza19udW1iZXIsIFRpbWUpICU+JQogIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQ0ZVX21MID4wKSAlPiUgI3JlbW92ZSBhbnkgdmFsdWVzIHRoYXQgaGFkIDAgY291bnRzIG9uIHRoZSBwbGF0ZSBmb3IgZ3JhcGhpbmcKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICNDYWxjdWxhdGUgcGxhdGUgY291bnRzIHVzaW5nIHRlY2huaWNhbCByZXBsaWNhdGVzIGZvciBlYWNoIGZsYXNrIGF0IGVhY2ggdGltZSBwb2ludAogICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVGVjaG5pY2FsX21lYW5fQ0ZVX21MID0gbWVhbihDRlVfbUwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVjaG5pY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKENGVV9tTCkpICU+JQogICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICNDYWxjdWxhdGUgcGxhdGUgY291bnRzIHVzaW5nIGF2ZXJhZ2Ugb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgZm9yIGFsbCBmbGFza3MgKGJpb2xvZ2ljYWwgcmVwbGljYXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoU3RyYWluLCBXaXJlX3RyZWF0bWVudCwgRE1TT190cmVhdG1lbnQsIFRpbWUpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKEJpb2xvZ2ljYWxfbWVhbl9DRlVfbUwgPSBtZWFuKFRlY2huaWNhbF9tZWFuX0NGVV9tTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW9sb2dpY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKFRlY2huaWNhbF9tZWFuX0NGVV9tTCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgI3Bsb3R0aW5nIHNjcmlwdAogICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1UaW1lLCB5ID0gbG9nMTAoQmlvbG9naWNhbF9tZWFuX0NGVV9tTCksIGNvbG91ciA9IFN0cmFpbl9vcmRlcmVkKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KHNpemUgPSA2KSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBsb2cxMChCaW9sb2dpY2FsX21lYW5fQ0ZVX21MIC0gQmlvbG9naWNhbF9zdGRldl9DRlVfbUwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bWF4ID0gbG9nMTAoQmlvbG9naWNhbF9tZWFuX0NGVV9tTCArIEJpb2xvZ2ljYWxfc3RkZXZfQ0ZVX21MKSkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IEZsYXNrX251bWJlciwgY29sb3IgPSBTdHJhaW5fb3JkZXJlZCkpKwogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDE2OCwgYnkgPSAyNCkpKwogICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9ncmlkKH4gV2lyZV90cmVhdG1lbnQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYigiTG9nMTBcbihDRlUvbUwpIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfbWF0aCgpLCBsaW1pdHMgPSBjKDUsIDEwKSkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIoIlRpbWUgZWxhcHNlZCAoaG91cnMpIikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiU3RyYWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcxIiwgbiA9IDQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpbGQgdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oaXRhbGljKCLiiIZwaHoiKSkpKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMikpCiAgICAgICAgICAKR3Jvd3RoX2N1cnZlc19sb2dfc2NhbGUKCkdyb3d0aF9jdXJ2ZXNfbG9nX3NjYWxlX25vX2xlZ2VuZF9hbmdsZWQgPC0gR3Jvd3RoX2N1cnZlc19sb2dfc2NhbGUgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkKCmdnc2F2ZSgiRmlnM19wbGF0ZV9jb3VudF9kYXRhX1dUX3Boel9tdXRhbnRfc2NhdHRlcnBsb3RfbG9nMTAuanBnIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjAsIGRldmljZT1qcGVnKQpnZ3NhdmUoIkZpZzNfcGxhdGVfY291bnRfZGF0YV9XVF9waHpfbXV0YW50X3NjYXR0ZXJwbG90X2xvZzEwLnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMCwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnM19wbGF0ZV9jb3VudF9kYXRhX1dUX3Boel9tdXRhbnRfc2NhdHRlcnBsb3RfbG9nMTAucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjAsIGRldmljZT1jYWlyb19wZGYpCmBgYAojIEZpZ3VyZSBTNTogQ29iYWx0IGNvbmNlbnRyYXRpb25zIGZvciB3aWxkIHR5cGUgY2VsbHMgdGhhdCB3ZXJlIGFjaWRpZmllZCB0aGVuIGZpbHRlcmVkLCBvciBmaWx0ZXJlZCB0aGVuIGFjaWRpZmllZAoKMS4gVXNlIHRoZSBjb2RlIGJlbG93IHRvIGxvYWQgaW4gc291cmNlIGRhdGEuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgPC0gZnJlYWQoIkFsbF9jb2JhbHRfSUNQTVNfZGF0YV9jbGVhbmVkX2Zvcm1hdHRlZF8yMDI1MDUxMy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCmBgYAoKMi4gVXNlIHRoaXMgY29kZSB0byBjcmVhdGUgYSBzaW1pbGFyIGZpZ3VyZSB0byBGaWd1cmUgMSBjb21wYXJpbmcgd2lsZCB0eXBlIGFuZCBzdGVyaWxlIG1lZGl1bSB0cmVhdG1lbnRzIHRoYXQgZGlkIG5vdCByZWNlaXZlIERNU08gYW5kIHdlcmUgc3ViamVjdCB0byBkaWZmZXJlbnQgc2FtcGxlIHByZXNlcnZhdGlvbiBtZXRob2RzLgpgYGB7cn0KI0FkanVzdCB0aGUgcHJlc2VudGF0aW9uIGFlc3RoZXRpY3MKdGhlbWU8LSB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDMyLCBhbmdsZSA9IDAsIGhqdXN0ID0gLjUsIHZqdXN0ID0gLjUsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzIsIGFuZ2xlID0gMCwgaGp1c3QgPSAxLCB2anVzdCA9IDAsIGZhY2UgPSAicGxhaW4iKSwgIAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzQsIGFuZ2xlID0gMCwgaGp1c3QgPSAuNSwgdmp1c3QgPSAwLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDM0LCBhbmdsZSA9IDkwLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMyLCBjb2xvdXIgPSAiZ3JleTIwIiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMiwgY29sb3VyID0gImdyZXkyMCIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMwLCBmYWNlID0gImJvbGQiLCBoanVzdCA9IC41KSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MzIsIGZhY2UgPSAiYm9sZCIpLCAKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0zMiksCiAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGw9TkEsIHNpemU9MSkpCgoKI0dyYXBoaW5nIHNjcmlwdCB3aXRoIGFkZGl0aW9uYWwgZGF0YSBtYW5pcHVsYXRpb24KQWNpZGlmeV9maWx0ZXJfc2NhdHRlcnBsb3QgPC0gIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXaXJlX3RyZWF0bWVudCA9PSAiV2lyZSBpbmNsdWRlZCIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQWJpb3RpY192c19iaW90aWMgPT0gIldpbGQgdHlwZSIgfCBBYmlvdGljX3ZzX2Jpb3RpYyA9PSAiU3RlcmlsZSBtZWRpdW0iKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihNZXRhYm9saXRlX3RyZWF0bWVudCA9PSAiTm90aGluZyBhZGRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKERNU09fdHJlYXRtZW50ID09ICJObyBETVNPIikgJT4lICM5NiBvYnNlcnZhdGlvbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KEFiaW90aWNfdnNfYmlvdGljLCBXaXJlX3RyZWF0bWVudCwgRE1TT190cmVhdG1lbnQsIE1ldGFib2xpdGVfdHJlYXRtZW50LCBUaW1lLCBTYW1wbGVfcHJlc2VydmF0aW9uKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wgPSBtZWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbl9jb2JhbHRfY29uY2VudHJhdGlvbl91Z19MID0gbWVkaWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wgPSBzZChDb2JhbHRfY29uY2VudHJhdGlvbl91Z19MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IG1pbihDb2JhbHRfY29uY2VudHJhdGlvbl91Z19MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXhfY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IG1heChDb2JhbHRfY29uY2VudHJhdGlvbl91Z19MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gbWVhbihDb2JhbHRfY29uY2VudHJhdGlvbl91TSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gbWVkaWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGRldl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSA9IHNkKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0gPSBtaW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heF9jb2JhbHRfY29uY2VudHJhdGlvbl91TSA9IG1heChDb2JhbHRfY29uY2VudHJhdGlvbl91TSkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxvY2F0ZShNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0w6TWF4X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFmdGVyID0gQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighQm90dGxlX251bWJlciA9PSAiMSIpICU+JSAjcmVtb3ZlIG91dGxpZXIgc3RlcmlsZSBjb250cm9sCiAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNwbG90dGluZyBzY3JpcHQKICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1UaW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBBYmlvdGljX3ZzX2Jpb3RpYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDYpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSAtIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHltYXggPSBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNICsgU3RkZXZfY29iYWx0X2NvbmNlbnRyYXRpb25fdU0pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IEJvdHRsZV9udW1iZXIsIGNvbG9yID0gQWJpb3RpY192c19iaW90aWMpKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDE2OCwgYnkgPSAyNCkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9ncmlkKH4gU2FtcGxlX3ByZXNlcnZhdGlvbikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIoIkNvYmFsdCBjb25jZW50cmF0aW9uICjCtU0pIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIoIlRpbWUgZWxhcHNlZCAoaG91cnMpIikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJBYmlvdGljIHZzIGJpb3RpYyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiQ2F2YWxjYW50aTEiLCBuID0gMikpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNzY2FsZV9zaGFwZV9kaXNjcmV0ZShuYW1lID0gIkFiaW90aWMgdnMgYmlvdGljIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gLTIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQoKQWNpZGlmeV9maWx0ZXJfc2NhdHRlcnBsb3QKCiNTYXZlIHRoZSBpbWFnZXMgaW4gZGlmZmVyZW50IGZvcm1hdHMKZ2dzYXZlKCJGaWdTNV9jb2JhbHRfSUNQTVNfZGF0YV9zYW1wbGVfcHJlc2VydmF0aW9uX3NjYXR0ZXJwbG90LmpwZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTgsIHdpZHRoPTIwLCBkZXZpY2U9anBlZykKZ2dzYXZlKCJGaWdTNV9jb2JhbHRfSUNQTVNfZGF0YV9zYW1wbGVfcHJlc2VydmF0aW9uX3NjYXR0ZXJwbG90LnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMCwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnUzVfY29iYWx0X0lDUE1TX2RhdGFfc2FtcGxlX3ByZXNlcnZhdGlvbl9zY2F0dGVycGxvdC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMCwgZGV2aWNlPWNhaXJvX3BkZikKYGBgCgojIEZpZ3VyZSBTNi4gRG9zZSByZXNwb25zZSBjdXJ2ZXMgZm9yIHdpbGQgdHlwZSBjZWxsIGdyb3d0aCByYXRlIGFzIGEgZnVuY3Rpb24gb2YgY29iYWx0IGNvbmNlbnRyYXRpb24KCjEuIExvYWQgdGhlIHN1bW1hcmllcyBnZW5lcmF0ZWQgd2l0aCB0aGUgJ2dyb3d0aGN1cnZlcicgcGFja2FnZSB0aGF0IGFyZSB0aGUgc291cmNlIGRhdGEgZm9yIHRoZSBkb3NlIHJlc3BvbnNlIGN1cnZlLgpgYGB7cn0KUF9jaGxvcl9hdXJfZ3Jvd3RoX3N1bW1hcnlfdmFyaWFibGVzX2FkZGVkIDwtIGZyZWFkKCJQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZWZvY2llbnNfZ3Jvd3RoX2N1cnZlX3N1bW1hcmllcy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCmBgYAoKMi4gVXNlIHRoZSBjb21tYW5kcyBpbiB0aGUgJ2RyYycgcGFja2FnZSB0byBmaXQgYSA1IHBhcmFtZXRlciBsb2dpc3RpYyByZWdyZXNzaW9uIHRvIGNyZWF0ZSB0aGUgZG9zZSByZXNwb25zZSBjdXJ2ZS4gVXNlIHRoZSBzdW1tYXJ5IGNvbW1hbmRzIHRvIGdldCBxdWljayBpbmZvcm1hdGlvbiBvbiB0aGUgSUMvRUM1MCB2YWx1ZXMgZm9yIGNvYmFsdCBjb25jZW50cmF0aW9uLgpgYGB7cn0KUF9jaGxvcl9hdXJfZ3Jvd3RoX3JhdGVfNV9wYXJhbV9tb2RlbDwtIGRybShyIH4gQ29iYWx0X2NvbmNlbnRyYXRpb25fdU1fbnVtZXJpYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IFBfY2hsb3JfYXVyX2dyb3d0aF9zdW1tYXJ5X3ZhcmlhYmxlc19hZGRlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmN0ID0gTEwuNSgpKQoKc3VtbWFyeShQX2NobG9yX2F1cl9ncm93dGhfcmF0ZV81X3BhcmFtX21vZGVsKQpQX2NobG9yX2F1cl9ncm93dGhfcmF0ZV9zdW1tYXJ5X2Rvc2VfZGF0YSA8LSBFRChQX2NobG9yX2F1cl9ncm93dGhfcmF0ZV81X3BhcmFtX21vZGVsLCBjKDUsIDEwLCA1MCksIGludGVydmFsID0gImRlbHRhIikKYGBgCgozLiBQbG90IHRoZSBkb3NlIHJlc3BvbnNlIGN1cnZlIHVzaW5nIGJhc2UgUiAobW9zdCBjb21wYXRpYmxlIHdpdGggdGhlIGRyYyBwYWNrYWdlKS4KYGBge3J9ClBfY2hsb3JfYXVyX2dyb3d0aF9yYXRlX2Rvc2VfcmVzcG9uc2U8LSBwbG90KFBfY2hsb3JfYXVyX2dyb3d0aF9yYXRlXzVfcGFyYW1fbW9kZWwsIGJyb2tlbiA9IEZBTFNFLCB0eXBlID0gImFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIkNvKDIrKSBjb25jZW50cmF0aW9uICjCtU0pIiwgeGxpbSA9IGMoMCwgMTAwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiID0gIkdyb3d0aCByYXRlIChoci0xKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFpbiA9ICJQc2V1ZG9tb25hcyBjaGxvcm9yYXBoaXMgYXVyZW9mYWNpZW5zIGdyb3d0aCBjdXJ2ZSBpbiByZXNwb25zZSB0byBDbygyKykiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCnZpZXcoUF9jaGxvcl9hdXJfZ3Jvd3RoX3JhdGVfZG9zZV9yZXNwb25zZSkKCiNTYXZlIGFzIHBkZiB1c2luZyBiYXNlIFIKcGRmKGZpbGUgPSAnRmlnUzZfUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19ncm93dGhfcmF0ZV9jb2JhbHRfZG9zZV9yZXNwb25zZV9jdXJ2ZS5wZGYnKQpwbG90KFBfY2hsb3JfYXVyX2dyb3d0aF9yYXRlXzVfcGFyYW1fbW9kZWwsIGJyb2tlbiA9IEZBTFNFLCB0eXBlID0gImFsbCIsCnhsYWIgPSAiQ28oMispIGNvbmNlbnRyYXRpb24gKMK1TSkiLCB4bGltID0gYygwLCAxMDAwKSwKeWxhYiA9ICJHcm93dGggcmF0ZSAoaHItMSkiLCAKbWFpbiA9ICJQc2V1ZG9tb25hcyBjaGxvcm9yYXBoaXMgYXVyZW9mYWNpZW5zIFxuZ3Jvd3RoIGN1cnZlIGluIHJlc3BvbnNlIHRvIENvKDIrKSIpCmRldi5vZmYoKQpgYGAKCiNGaWd1cmUgUzE0OiBBTk9WQSB0ZXN0IG9uIGxpdmUgY2VsbHMgd2l0aCBhbmQgd2l0aG91dCBETVNPCgoxLiBMb2FkIHRoZSBzb3VyY2UgZGF0YSBhbmQgdHJpbSBpdCB0byB0aGUgZGVzaXJlZCBzYW1wbGVzIHRvIGNhcnJ5IG91dCB0aGUgY29tcGFyaXNvbiBmb3IgdGhlIGVmZmVjdCBvZiBETVNPLgpgYGB7cn0KQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkIDwtIGZyZWFkKCJBbGxfY29iYWx0X0lDUE1TX2RhdGFfY2xlYW5lZF9mb3JtYXR0ZWRfMjAyNTA1MTMudHh0Iiwgc2VwID0gIlx0IiwgaGVhZGVyID0gImF1dG8iKQoKI1N1YmV0IERNU08gZGF0YQpETVNPX2NvbXBhcmlzb25fZGF0YSA8LSBBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXaXJlX3RyZWF0bWVudCA9PSAiV2lyZSBpbmNsdWRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoVGltZSA9PSAxNjgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQWJpb3RpY192c19iaW90aWMgPT0gIldpbGQgdHlwZSIpCmBgYAoKMi4gVXNlIHRoZSBzdWJzZXQgZGF0YSB0byBnZW5lcmF0ZSBhIGxpbmVhciBtb2RlbCB0aGF0IGZvciBhbiBBTk9WQSBjb21wYXJpc29uLiBVc2UgdGhpcyBjb2RlIHRvIHZlcmlmeSB0aGUgYXNzdW1wdGlvbnMgb2YgbGluZWFyIG1vZGVsIGZpdC4KYGBge3J9CkRNU09fY29tcGFyaXNvbl9tb2RlbCA8LSBsbShDb2JhbHRfY29uY2VudHJhdGlvbl91TSB+IERNU09fdHJlYXRtZW50LCBkYXRhID0gRE1TT19jb21wYXJpc29uX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFzdHMgPSBsaXN0KERNU09fdHJlYXRtZW50ID0gY29udHIuc3VtKSwgdHlwZSA9MykgI25lZWQgdG8gZG8gdGhpcyBmb3IgdW5hYmFsYW5jZSBzYW1wbGUgc2l6ZQpETVNPX2NvbXBhcmlzb25fbW9kZWwKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KERNU09fY29tcGFyaXNvbl9tb2RlbCkKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KLSBMb29rcyBsaWtlIHdlIG1heSBoYXZlIGlzc3VlcyB3aXRoIGVxdWFsIHZhcmlhbmNlIGluIHRoZSBhYnNlbmNlIG9mIERNU08uCi0gTm9ybWFsaXR5IGxvb2tzIHByZXR0eSBnb29kIGV4Y3BldCBmb3IgdGhlIDV0aCBhbmQgN3RoIGRhdGEgcG9pbnRzLgoKMy4gUnVuIGZvcm1hbCB0ZXN0cyB0byB2ZXJpZnkgdGhlIGFzc3VtcHRpb25zIG9mIGxpbmVhciBtb2RlbHMuCmBgYHtyfQojUnVuIEJyZXVzY2ggUGFnYW4gdGVzdCBmb3IgaG9tb3NjZWRhc3RpY2l0eQpicHRlc3QoRE1TT19jb21wYXJpc29uX21vZGVsKQoKI1J1biBTaGFwaXItV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoRE1TT19jb21wYXJpc29uX21vZGVsJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KERNU09fY29tcGFyaXNvbl9tb2RlbCkKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KCnN0dWRlbnRpemVkIEJyZXVzY2gtUGFnYW4gdGVzdAoKZGF0YTogIERNU09fY29tcGFyaXNvbl9tb2RlbApCUCA9IDYuNTQ5NywgZGYgPSAzLCBwLXZhbHVlID0gMC4wODU1NyAqcCA+IDAuMDUqIG1lYW5pbmcgd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHksIHRoaXMgaXMgZ29vZCAoanVzdCBiYXJlbHkpCgoKU2hhcGlyby1XaWxrIG5vcm1hbGl0eSB0ZXN0CgpkYXRhOiAgRE1TT19jb21wYXJpc29uX21vZGVsJHJlc2lkdWFscwpXID0gMC43MjIwNCwgcC12YWx1ZSA9IDAuNzU2OSAqcCA+MC4wNSosIG1lYW5pbmcgd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgoKCkR1cmJpbi1XYXRzb24gdGVzdAoKZGF0YTogIERNU09fY29tcGFyaXNvbl9tb2RlbApEVyA9IDEuOTc4MywgcC12YWx1ZSA9IDAuMjE0MQoKQWx0ZXJuYXRpdmUgaHlwb3RoZXNpczogdHJ1ZSBhdXRvY29ycmVsYXRpb24gaXMgZ3JlYXRlciB0aGFuIDAgKnZhbHVlIGlzIGNsb3NlIHRvIDIsIG5vIHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbiosICpwID4gMC4wNSogc28gd2UgY2FuJ3QgcmVqZWN0IG51bGwgaHlwb3RoZXNpcyBvZiBubyBhdXRvY29ycmVsYXRpb24KCjMuIFJ1biB0aGUgQU5PVkEgYW5kIHRoZSBUdWtleSBjb21wYXJpc29uLgpgYGB7cn0KRE1TT190eXBlX0lJSV9BTk9WQV9yZXN1bHRzIDwtIEFub3ZhKERNU09fY29tcGFyaXNvbl9tb2RlbCwgdHlwZSA9IDMpCkRNU09fdHlwZV9JSUlfQU5PVkFfcmVzdWx0cwpgYGAKCiMjIyBJbnRlcnByZXRhdGlvbgotIERNU08gdHJlYXRtZW50IGhhZCBhIHNpZ25pZmljYW50IGVmZmVjdCBvbiBjb2JhbHQgY29uY2VudHJhdGlvbiBhdCAxNjggaG91cnMgZm9yIHdpbGQgdHlwZSBjZWxsIGV4cGVyaW1lbnRzLgoKNC4gQ3JlYXRlIGEgYm94cGxvdCB0byBpbGx1c3RyYXRlIHRoaXMgcmVzdWx0LiBUaGVyZSBpcyBubyBuZWVkIHRvIGFubm90YXRlIGJlY2F1c2UgdGhlcmUgYXJlIG9ubHkgdHdvIGJveGVzIGFuZCB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUgd2FzIHNpZ25pZmljYW50LiAKYGBge3J9CnRoZW1lPC0gdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzMiwgYW5nbGUgPSAwLCBoanVzdCA9IC41LCB2anVzdCA9IC41LCBmYWNlID0gInBsYWluIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDMyLCBhbmdsZSA9IDAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLCBmYWNlID0gInBsYWluIiksICAKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDM0LCBhbmdsZSA9IDAsIGhqdXN0ID0gLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzNCwgYW5nbGUgPSA5MCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMiwgY29sb3VyID0gImdyZXkyMCIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMzIsIGNvbG91ciA9ICJncmV5MjAiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAuNSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTMyLCBmYWNlID0gImJvbGQiKSwgCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MzIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBzaXplPTEpKQoKRE1TT19ib3hwbG90IDwtIERNU09fY29tcGFyaXNvbl9kYXRhICU+JQogICAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PURNU09fdHJlYXRtZW50LCB5PUNvYmFsdF9jb25jZW50cmF0aW9uX3VNKSkgKyAKICAgICAgICAgICAgICAgIGdlb21fYm94cGxvdCgpICsKICAgICAgICAgICAgICAgIGdlb21faml0dGVyKGZpbGwgPSAiZ3JleSIsIGNvbG91ciA9ICJibGFjayIsIHdpZHRoID0gMC4xLCBwY2ggPTIxLCBzdHJva2UgPTEpKwogICAgICAgICAgICAgICAgeWxpbSgwLCAzMDAwKSArCiAgICAgICAgICAgICAgICBsYWJzKHRpdGxlID0gIiIgLAogICAgICAgICAgICAgICAgeSA9ICJDb2JhbHRcbmNvbmNlbnRyYXRpb24gKMK1TSkiLCAKICAgICAgICAgICAgICAgIHggPSAiRE1TTyB0cmVhdG1lbnQiKSArCiAgICAgICAgICAgICAgICB0aGVtZSArCiAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQodmp1c3QgPSAtMiksCiAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQodmp1c3QgPSAyKSwKICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCkpCgpETVNPX2JveHBsb3QKCiNTYXZlIGRpZmZlcmVudCBpbWFnZSBmb3JtYXRzCmdnc2F2ZSgiRmlnUzE0X2NvYmFsdF9JQ1BNU19kYXRhX0RNU08uanBnIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MTAsIGRldmljZT1qcGVnKQpnZ3NhdmUoIkZpZ1MxNF9jb2JhbHRfSUNQTVNfZGF0YV9ETVNPLnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0xMCwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnUzE0X2NvYmFsdF9JQ1BNU19kYXRhX0RNU08ucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MTAsIGRldmljZT1jYWlyb19wZGYpCmBgYAojQmlvaW5mb3JtYXRpY3MgYW5hbHlzZXMgb2YgZ2Vub21lIGFubm90YXRpb25zIGdlbmVyYXRlZCB1c2luZyBEUkFNCgojIyBSdW4gRFJBTSBmb3IgYW5ub3RhdGlvbnMgYW5kIGRpc3RpbGxhdGlvbgoKMS4gQWN0aXZhdGUgdGhlIGNvbmRhIGVudmlyb25tZW50IGNvbnRhaW5pbmcgRFJBTSBhbmQgcnVuIHRoZSBhbm5vdGF0ZSBjb21tYW5kLiBSZXBsYWNlIHRoZSBkaXJlY3RvcnkgYW5kIGZhc3RhIGZpbGUgd2l0aCB0aGUgZ2Vub21lIGZpbGUgZm9yIFBzZXVkb21vbmFzIGNobG9yb3JhcGhpcyBzdWJzcGVjaWVzIGF1cmVmb2FjaWVucyAob3IgYW55IGdlbm9tZSBvciBnZW5vZW1zIG9mIHlvdXIgY2hvaWNlKQpgYGB7YmFzaH0KRFJBTS5weSBhbm5vdGF0ZSAtaSAnUHNldWRvbW9uYXNfZ2Vub21lX2FuYWx5c2VzLyouZmFzdGEnIC0tdXNlX3VuaXJlZiAtbyBQc2V1ZG9tb25hc19hbm5vdGF0aW9uX3dpdGhfdW5pcmVmIC0tdGhyZWFkcyA4CmBgYAoKMi4gT25jZSB0aGUgYW5ub3RhdGlvbiBpcyBjb21wbGV0ZSwgdXNlIHRoZSBkaXN0aWxsYXRpb24gY29tbWFuZC4gTWFrZSBzdXJlIHRvIHVzZSB0aGUgc2FtZSBvdXRwdXQgZGlyZWN0b3J5IGZyb20gdGhlIGFubm90YXRlIHN0ZXAuCmBgYHtiYXNofQpEUkFNLnB5IGRpc3RpbGwgLWkgUHNldWRvbW9uYXNfYW5ub3RhdGlvbl93aXRoX3VuaXJlZi9hbm5vdGF0aW9ucy50c3YgLW8gUHNldWRvbW9uYXNfZ2Vub21lX3N1bW1hcmllcyAtLXRybmFfcGF0aCBQc2V1ZG9tb25hc19hbm5vdGF0aW9uX3dpdGhfdW5pcmVmL3RybmFzLnRzdiAtLXJybmFfcGF0aCBQc2V1ZG9tb25hc19hbm5vdGF0aW9uX3dpdGhfdW5pcmVmL3JybmFzLnRzdgpgYGAKCiMjIE1hbnVhbGx5IHNlYXJjaCBmb3IgY29iYWx0IGdlbmVzIGluIHRoZSBhbm5vdGF0aW9uIG91dHB1dCBieSBEUkFNCgoxLiBMb2FkIGluIHRoZSB0YWItZGVsaW1pdGVkIGZpbGUgY29udGFpbmluZyB0aGUgYW5ub3RhdGlvbiBkYXRhLgpgYGB7cn0KUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19hbm5vdGF0aW9ucyA8LSBmcmVhZCgiUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19EUkFNX2Fubm90YXRpb25zLnRzdiIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikKYGBgCgoyLiBNYW51YWxseSBzZWFyY2ggdGhlIGFubm90YXRpb24gZmlsZSB1c2luZyBkaWZmZXJlbnQgc3RyaW5ncyBvZiB0ZXN0IGZvciBmdW5jdGlvbnMgcmVsZXZhbnQgdG8gY29iYWx0IGFuZCBtaWNyb2JpYWxseS1pbmR1Y2VkIGNvcnJvc2lvbi4KYGBge3J9CmNvcnJvc2lvbl9wYXRod2F5cyA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgI1NpbXBsZSB0ZXh0IHNlYXJjaCBmb3IgImNvYmFsdCIKICAgICAgICAgICAgICAgICAgIGZpbHRlcigKICAgICAgICAgICAgICAgICAgICAgKGlmX2FueShjKGtlZ2dfaGl0OnBmYW1faGl0cyksIH4gZ3JlcGwoImNvYmFsdCIsIC4pKSkgfAogICAgICAgICAgICAgICAgICAgICAoaWZfYW55KGMoa2VnZ19oaXQ6cGZhbV9oaXRzKSwgfiBncmVwbCgiY29iIiwgLikpKSB8CiAgICAgICAgICAgICAgICAgICAgIChpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJjeWFuaWRlIiwgLikpKXwKICAgICAgICAgICAgICAgICAgICAgKGlmX2FueShjKGtlZ2dfaGl0OnBmYW1faGl0cyksIH4gZ3JlcGwoImhjbiIsIC4pKSl8CiAgICAgICAgICAgICAgICAgICAgIChpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJjeXRvY2hyb21lIiwgLikpKXwKICAgICAgICAgICAgICAgICAgICAgIyhpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJoeWRyb2dlbmFzZSIsIC4pKSl8IHRoaXMgaXMgbm9uLXNwZWNpZmljIGFuZCBwaWNrcyB1cCBhbnl0aGluZyB3aXRoIGRlaHlkcm9nZW5hc2UsIGNvbW1lbnQgb3V0CiAgICAgICAgICAgICAgICAgICAgIChpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJzaWRlcm9waG9yZSIsIC4pKSkpICU+JQogICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3Qoc2NhZmZvbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0X3Bvc2l0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRfcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGtvX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBrZWdnX2hpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pcmVmX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1bmlyZWZfaGl0KQoKI1dyaXRlIHRoZSB0YWJsZSB0byBzYXZlIHRoZSBzb3VyY2UgZGF0YQp3cml0ZS50YWJsZShjb3Jyb3Npb25fcGF0aHdheXMsIGZpbGUgPSAiU3VwcERhdGFfUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19wdXRhdGl2ZV9jb3Jyb3Npb25fcGF0aHdheXMudHN2Iiwgc2VwID0gIlx0Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyMgU3VtbWFyeSBvZiBrZXkgYW50aVNNQVNIIGJpb3N5bnRoZXRpYyBnZW5lIGNsdXN0ZXIgcmVnaW9ucwoKKmtleSBiaW9zeW50aGV0aWMgZ2VuZXMqIGFyZSBkZW5vdGVkIGJ5IGFzdGVyaXNrcyBpbiBtYXJrZG93biBmb3JtYXQuCgojIyMgUmVnaW9uIDIgKGh5ZHJvZ2VuIGN5YW5pZGUgY2x1c3Rlcik6IDI5NTE0ODMgdG8gMjk2NDQ1NQpgYGB7cn0KUmVnaW9uMiA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JSBmaWx0ZXIoc3RhcnRfcG9zaXRpb24gPj0gMjk1MTQ4MyAmIGVuZF9wb3NpdGlvbiA8PTI5NjQ0NTUpCmBgYAoKR2VuZXMgaW4gaHlkcm9nZW4gY3lhbmlkZS1jbHVzdGVyOgotICpjdGcxXzI1OTEqOiAyOTU2NDgzIC0gMjk1NjgwMCAtLT4gaHlkcm9nZW4gY3lhbmlkZSBzeW50aGFzZSBIY25BIFtFQzoxLjQuOTkuNV0gKEMgZ3JhZGUsIEtFR0cgSUQgPSBLMTA4MTQpCi0gKmN0ZzFfMjU5Mio6IDI5NTY3OTcgLSAyOTU4MjA2IC0tPiBoeWRyb2dlbiBjeWFuaWRlIHN5bnRoYXNlIEhjbkIgW0VDOjEuNC45OS41XSAoQiBncmFkZSwgS0VHRyBJRCA9IEsxMDgxNSkKLSAqY3RnMV8yNTkzKjogMjk1ODE5OSAtIDI5NTk0NTUgLS0+IGh5ZHJvZ2VuIGN5YW5pZGUgc3ludGhhc2UgSGNuQyBbRUM6MS40Ljk5LjVdIChCIGdyYWRlLCBLRUdHIElEID0gSzEwODE2KQotIGN0ZzFfMjU5NDogMjk1OTYxOCAtIDI5NjAyMjMgLS0+IGdsdXRhdGhpb25lIFMtdHJhbnNmZXJhc2UgW0VDOjIuNS4xLjE4XSAoQiBncmFkZSwgS0VHRyBJRCA9IEswMDc5OSkKCiMjIyBSZWdpb24gNiAoTkktc2lkZXJvcGhvcmUpOiAzODMyODM3IHRvIDM4Njk4MjEKYGBge3J9ClJlZ2lvbjYgPC0gUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19hbm5vdGF0aW9ucyAlPiUgZmlsdGVyKHN0YXJ0X3Bvc2l0aW9uID49IDM4MzI4MzcgJiBlbmRfcG9zaXRpb24gPD0zODY5ODIxKQpgYGAKCkdlbmVzIGluIE5JLXNpZGVyb3Bob3JlIGNsdXN0ZXI6CgotICpjdGcxXzMzNzIqOiAzODQ2ODM3IC0gMzg0ODczNSAtLT4gKnN0YXBoeWxvZmVycmluKiBCIHN5bnRoYXNlIFtFQzo2LjMuMi41Nl0gKEIgZ3JhZGUgS0VHRyBJRCA9IEsyMzM3NSkKLSBjdGcxXzMzNzM6IDM4NDg3NDAgLSAzODQ5NTEzIC0tPiAqc3RhcGh5bG9mZXJyaW4qIEIgYmlvc3ludGhlc2lzIGNpdHJhdGUgc3ludGhhc2UgKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMjMzNzYpCi0gKmN0ZzFfMzM3NCo6IDM4NDk1MDcgLSAzODUxMzY5IC0tPiAyLVsoTC1hbGFuaW4tMy15bGNhcmJhbW95bCltZXRoeWxdLTMtKDItYW1pbm9ldGh5bGNhcmJhbW95bCktMi1oeWRyb3h5cHJvcGFub2F0ZSBzeW50aGFzZSBbRUM6Ni4zLjIuNTVdIChCIGdyYWRlLCBLRUdHIElEID0gSzIzMzc0KQotIGN0ZzFfMzM3NTogMzg1MTM5NCAtIDM4NTI4MTIgLS0+IFVuaVJlZjkwX0EwQTU1NFA3WTUgREhBMiBmYW1pbHkgZWZmbHV4IE1GUyB0cmFuc3BvcnRlciBwZXJtZWFzZSBzdWJ1bml0IG49MzAgVGF4PVBzZXVkb21vbmFkYWNlYWUgVGF4SUQ9MTM1NjIxIFJlcElEPUEwQTU1NFA3WTVfOVBTRUQgKEIgZ3JhZGUsIG5vIGhpdCBpbiBLRUdHKQotIGN0ZzFfMzM3NjogMzg1MjgwOSAtIDM4NTQwMjkgLS0+IGRpYW1pbm9waW1lbGF0ZSBkZWNhcmJveHlsYXNlIFtFQzo0LjEuMS4yMF0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDE1ODYpCi0gKmN0ZzFfMzM3Nyo6IDM4NTQwMjIgLSAzODU1ODIxIC0tPiBVbmlSZWY5MF9BMEEwQzVFTDY5IEFjc0QgcHJvdGVpbiBuPTcwIFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEEwQzVFTDY5XzlQU0VEIChCIGdyYWRlLCBubyBoaXQgaW4gS0VHRykKCiMjIyBSZWdpb24gNyAoaHlkcm9nZW4gY3lhbmlkZSBjbHVzdGVyKTogMzg4ODg1NCB0byAzOTAxNzAxCmBgYHtyfQpSZWdpb243IDwtIFBzZXVkb21vbmFzX2NobG9yb3JhcGhpc19hdXJlb2ZhY2llbnNfYW5ub3RhdGlvbnMgJT4lIGZpbHRlcihzdGFydF9wb3NpdGlvbiA+PSAzODg4ODU0ICYgZW5kX3Bvc2l0aW9uIDw9MzkwMTcwMSkKYGBgCgotIGN0ZzFfMzQwNTogMzg5MDk4NCAtIDM4OTI0NDEgLS0+IHN1Y2NpbmF0ZS1zZW1pYWxkZWh5ZGUgZGVoeWRyb2dlbmFzZSAvIGdsdXRhcmF0ZS1zZW1pYWxkZWh5ZGUgZGVoeWRyb2dlbmFzZSBbRUM6MS4yLjEuMTYgMS4yLjEuNzkgMS4yLjEuMjBdIChCIGdyYWRlLCBLRUdHIElEID0gSzAwMTM1KQotIGN0ZzFfMzQwNjogMzg5MjcwMCAtIDM4OTM4NTcgLS0+IGFjZXR5bG9ybml0aGluZSBkZWFjZXR5bGFzZSBbRUM6My41LjEuMTZdIChCIGdyYWRlLCBLRUdHIElEID0gSzAxNDM4KQotICpjdGcxXzM0MDcqOiAzODkzODU0IC0gMzg5NTAwOCAtLT4gVW5pUmVmOTBfQTBBQTQ1WElOMCBTYXJjb3NpbmUgb3hpZGFzZSBzdWJ1bml0IGJldGEgbj01IFRheD1Qc2V1ZG9tb25hcyBUYXhJRD0yODYgUmVwSUQ9QTBBQTQ1WElOMF85UFNFRCAobm8gS0VHRyBoaXQsIEIgZ3JhZGUsIFVuaVJlZiBJRCA9IEEwQUE0NVhJTjBfOVBTRUQpCiAgLSBDYXRhbHl6ZXMgb3hpZGF0aXZlIGRlbWV0aHlsYXRpb24gb2Ygc2FyY29zaW5lIChOLW1ldGh5bGdseWNpbmUpIHRvIHlpZWxkIGdseWNpbmUKLSAqY3RnMV8zNDA4KjogMzg5NTAwNSAtIDM4OTY0MTEgLS0+IFVuaVJlZjkwX0EwQTNHN0swRTIgT3BpbmUgb3hpZGFzZSBzdWJ1bml0IEEgbj0zOSBUYXg9UHNldWRvbW9uYXMgVGF4SUQ9Mjg2IFJlcElEPUEwQTNHN0swRTJfOVBTRUQsIChubyBLRUdHIGhpdCwgQiBncmFkZSwgVW5pcmVmIElEID0gQTBBM0c3SzBFMl85UFNFRCkKICAtIENsZWF2ZXMgb3BpbmVzIGludG8gYW1pbm8gYWNpZHMgYW5kIHB5cnV2YXRlCi0gKmN0ZzFfMzQwOSo6IDM4OTYzOTMgLSAzODk2NzAxIC0tPiBVbmlSZWY5MF9BMEE1TTdDVEQxICgyRmUtMlMpLWJpbmRpbmcgcHJvdGVpbiBuPTE0IFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEE1TTdDVEQxXzlQU0VEIChDIGdyYWRlLCBubyBLRUdHIGhpdCwgVW5pUmVmIElEID0gQTBBNU03Q1REMV85UFNFRCkKLSBjdGcxXzM0MTA6IDM4OTY2OTggLSAzODk4NTM5IC0tPiBwZXB0aWRlL25pY2tlbCB0cmFuc3BvcnQgc3lzdGVtIEFUUC1iaW5kaW5nIHByb3RlaW4gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDIwMzEpCi0gY3RnMV8zNDExOiAzODk4NTQxIC0gMzg5OTQxNiAtLT4gVW5pUmVmOTBfQTBBMEMxWlNVNiBETkEtZGlyZWN0ZWQgUk5BIHBvbHltZXJhc2Ugc3VidW5pdCBhbHBoYSBuPTMwIFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEEwQzFaU1U2X1BTRUZMIChubyBLRUdHIGhpdCwgQiBncmFkZSwgVW5pcmVmIElEID0gQTBBMEMxWlNVNl9QU0VGTCkKLSBjdGcxXzM0MTI6IDM4OTk0MTMgLSAzOTAwMzY5IC0tPiBwZXB0aWRlL25pY2tlbCB0cmFuc3BvcnQgc3lzdGVtIHBlcm1lYXNlIHByb3RlaW4gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDIwMzMpCgojIyMgUmVnaW9uIDEwIChOUlAtbWV0YWxsb3Bob3JlKTogNTA1NjQzNCB0byA1MTU1NDA3CmBgYHtyfQpSZWdpb24xMCA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JSBmaWx0ZXIoc3RhcnRfcG9zaXRpb24gPj0gNTA1NjQzNCAmIGVuZF9wb3NpdGlvbiA8PTUxNTU0MDcpCmBgYAoKLSAqY3RnMV80NDc0KjogNSwwNzYsNDM0IC0gNSwwNzcsNzY4IC0tPiBMLW9ybml0aGluZSBONS1tb25vb3h5Z2VuYXNlIFtFQzoxLjE0LjEzLjE5NSAxLjE0LjEzLjE5Nl0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMTA1MzEpCi0gY3RnMV80NDc1OiA1LDA3Nyw5MDAgLSA1LDA3OCw0OTYgLS0+IFVuaVJlZjkwX0EwQTE2NVlHWDQgUk5BIHBvbHltZXJhc2Ugc3VidW5pdCBzaWdtYSBuPTQgVGF4PVBzZXVkb21vbmFzIFRheElEPTI4NiBSZXBJRD1BMEExNjVZR1g0X1BTRUZMIChDIGdyYWRlLCBubyBLRUdHIElEKQotIGN0ZzFfNDQ3NjogNSwwNzgsNzE2IC0gNSwwNzksODg4IC0tPiBtZW1icmFuZSBmdXNpb24gcHJvdGVpbiwgbWFjcm9saWRlLXNwZWNpZmljIGVmZmx1eCBzeXN0ZW0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMTM4ODgpCi0gY3RnMV80NDc3OiA1LDA3OSw4ODkgLSA1LDA4MSw4NjIgLS0+IG1hY3JvbGlkZSB0cmFuc3BvcnQgc3lzdGVtIEFUUC1iaW5kaW5nL3Blcm1lYXNlIHByb3RlaW4gW0VDOjcuNi4yLi1dIChCIGdyYWRlLCBLRUdHIElEID0gSzA1Njg1KQotIGN0ZzFfNDQ3ODogNSwwODEsODcwIC0gNSwwODMsMjc5IC0tPiBvdXRlciBtZW1icmFuZSBwcm90ZWluLCBtdWx0aWRydWcgZWZmbHV4IHN5c3RlbSAoQiBncmFkZSwgS0VHRyBJRCA9IEsxODEzOSkKLSAqY3RnMV80NDc5KjogNSwwODMsMzU1IC0gNSwwODQsOTc3IC0tPiBVbmlSZWY5MF9BMEE1NTRQQUMwIFR3aW4tYXJnaW5pbmUgdHJhbnNsb2NhdGlvbiBzaWduYWwgZG9tYWluLWNvbnRhaW5pbmcgcHJvdGVpbiBuPTE5IFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEE1NTRQQUMwXzlQU0VEIChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSBjdGcxXzQ0ODA6IDUsMDg1LDE4NiAtIDUsMDg2LDU5NSAtLT4gbWVtYnJhbmUgZGlwZXB0aWRhc2UgW0VDOjMuNC4xMy4xOV0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDEyNzMpCi0gY3RnMV80NDgxOiA1LDA4Niw2MTcgLSA1LDA4Nyw5MTUgLS0+IFVuaVJlZjkwX0EwQTJDOUVRTjEgSXNvcGVuaWNpbGxpbiBOIGVwaW1lcmFzZSBDZWZEIG49NTYgVGF4PVBzZXVkb21vbmFkYWNlYWUgVGF4SUQ9MTM1NjIxIFJlcElEPUEwQTJDOUVRTjFfUFNFUEggKEIgZ3JhZGUsIG5vIEtFR0cgaGl0KQotICpjdGcxXzQ0ODIqOiA1LDA4Nyw5NTkgLSA1LDA4OCw4NTUgLS0+IFVuaVJlZjkwX1E0Szk5NyBDaHJvbW9waG9yZSBtYXR1cmF0aW9uIHByb3RlaW4gKlB2ZE8qIG49NTUgVGF4PVBzZXVkb21vbmFkYWNlYWUgVGF4SUQ9MTM1NjIxIFJlcElEPVE0Szk5N19QU0VGNSAoQiBncmFkZSwgbm8gS0VHRyBoaXQpCi0gY3RnMV80NDgzOiA1LDA4OCw5MTAgLSA1LDA4OSw3NzMgLS0+IFVuaVJlZjkwX1E0Szk5NiBwaG9zcGhvcmlib3N5bGdseWNpbmFtaWRlIGZvcm15bHRyYW5zZmVyYXNlIDEgbj00OSBUYXg9UHNldWRvbW9uYWRhY2VhZSBUYXhJRD0xMzU2MjEgUmVwSUQ9UTRLOTk2X1BTRUY1IChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSBjdGcxXzQ0ODQ6IDUsMDg5LDk2MSAtIDUsMDkxLDYxMyAtLT4gcHV0YXRpdmUgcHlvdmVyZGluIHRyYW5zcG9ydCBzeXN0ZW0gQVRQLWJpbmRpbmcvcGVybWVhc2UgcHJvdGVpbiAoQiBncmFkZSwgS0VHRyBJRCA9IEswNjE2MCkKLSBjdGcxXzQ0ODU6IDUsMDkxLDcxNCAtIDUsMDk0LDE4MiAtLT4gb3V0ZXItbWVtYnJhbmUgcmVjZXB0b3IgZm9yIGZlcnJpYyBjb3Byb2dlbiBhbmQgZmVycmljLXJob2RvdG9ydWxpYyBhY2lkIChCIGdyYWRlLCBLRUdHIElEID0gSzE2MDg4KQotICpjdGcxXzQ0ODYqOiA1LDA5NCw1NzAgLSA1LDEwNyw4MDUgLS0+IFVuaVJlZjkwX0EwQTU1NFBBQjYgQW1pbm8gYWNpZCBhZGVueWxhdGlvbiBkb21haW4tY29udGFpbmluZyBwcm90ZWluIG49MjIgVGF4PVBzZXVkb21vbmFzIFRheElEPTI4NiBSZXBJRD1BMEE1NTRQQUI2XzlQU0VEIChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSAqY3RnMV80NDg3KjogNSwxMDcsODE4IC0gNSwxMTQsNDE0IC0tPiBVbmlSZWY5MF9BMEE1NTRQQUMyIE5vbi1yaWJvc29tYWwgcGVwdGlkZSBzeW50aGV0YXNlIG49MjYgVGF4PVBzZXVkb21vbmFzIFRheElEPTI4NiBSZXBJRD1BMEE1NTRQQUMyXzlQU0VEIChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSAqY3RnMV80NDg4KjogNSwxMTQsNDE0IC0gNSwxMjUsNTc2IC0tPiBVbmlSZWY5MF9VUEkwMDI0MDdDOUREIGFtaW5vIGFjaWQgYWRlbnlsYXRpb24gZG9tYWluLWNvbnRhaW5pbmcgcHJvdGVpbiBuPTQgVGF4PVBzZXVkb21vbmFzIGNobG9yb3JhcGhpcyBUYXhJRD01ODc3NTMgUmVwSUQ9VVBJMDAyNDA3QzlERCAoQiBncmFkZSwgbm8gS0VHRyBoaXQpCgojIyMgUmVnaW9uIDExIChOUlBTKTogNTE4OTQ1NiB0byA1MjQyNDcyCmBgYHtyfQpSZWdpb24xMSA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JSBmaWx0ZXIoc3RhcnRfcG9zaXRpb24gPj0gNTE4OTQ1NiAmIGVuZF9wb3NpdGlvbiA8PTUyNDI0NzIpCmBgYAoKTlJQUyByZWdpb24gaGVyZSBpcyByZWFsbHkgb25seSBvbmUgZ2VuZToKLSAqY3RnMV80NTYzKjogNTIwOTQ1NiAtIDUyMjI0NzIgLS0+IFVuaVJlZjkwX0EwQTU1NFBFTDcgTm9uLXJpYm9zb21hbCBwZXB0aWRlIHN5bnRoZXRhc2Ugbj0yOSBUYXg9UHNldWRvbW9uYWRhY2VhZSBUYXhJRD0xMzU2MjEgUmVwSUQ9QTBBNTU0UEVMN185UFNFRCAoQiBncmFkZSwgbm8gS0VHRyBoaXQpCgo=